diff --git a/.flake8 b/.flake8 index 0335236f..b2811baa 100644 --- a/.flake8 +++ b/.flake8 @@ -16,3 +16,6 @@ ignore = # Unused imports - pb with import_and_args.py # F401 +per-file-ignores = + # __init__ files + dataset_product_mapping.py: E501 diff --git a/README.md b/README.md index 3f8a0486..219cd150 100644 --- a/README.md +++ b/README.md @@ -72,15 +72,6 @@ python -m pip install copernicusmarine --upgrade For more comprehensive details on how to use the `copernicusmarine` Toolbox, please refer to our [Help Center](https://help.marine.copernicus.eu/en/collections/9080063-copernicus-marine-toolbox). It ensures a smooth migration for existing users of legacy services such as MOTU, OPeNDAP or FTP. -### General configuration - -#### Cache Usage - -Cachier library is used for caching part of the requests (as result of `describe` or `login`). By default, the cache will be located in the home folder. If you need to change the location of the cache, you can set the environment variable `COPERNICUSMARINE_CACHE_DIRECTORY` to point to the desired directory: - -- on **UNIX** platforms: `export COPERNICUSMARINE_CACHE_DIRECTORY=` -- on **Windows** platforms: `set COPERNICUSMARINE_CACHE_DIRECTORY=` - ### Network configuration #### Disable SSL @@ -543,10 +534,8 @@ copernicusmarine subset --request-file template_subset_data_request.json "force_download": false, "log_level": "INFO", "no_directories": false, - "no_metadata_cache": false, "output_directory": "./data/", "overwrite_output_data": false, - "overwrite_metadata_cache": false, "show_outputnames": true } ``` diff --git a/copernicusmarine/catalogue_parser/catalogue_parser.py b/copernicusmarine/catalogue_parser/catalogue_parser.py index f7ae1f71..a607387c 100644 --- a/copernicusmarine/catalogue_parser/catalogue_parser.py +++ b/copernicusmarine/catalogue_parser/catalogue_parser.py @@ -1,23 +1,24 @@ import asyncio import logging -import re -from abc import ABC, abstractmethod from dataclasses import dataclass -from datetime import timedelta from enum import Enum -from importlib.metadata import version as package_version from itertools import groupby -from typing import Any, Dict, Iterator, List, Optional, Tuple, Union +from typing import Any, Dict, Iterator, List, Optional, Tuple import nest_asyncio import pystac from aiohttp import ContentTypeError, ServerDisconnectedError -from cachier.core import cachier from tqdm import tqdm from copernicusmarine.aioretry import RetryInfo, RetryPolicyStrategy, retry -from copernicusmarine.command_line_interface.exception_handler import ( - log_exception_debug, +from copernicusmarine.catalogue_parser.dataset_product_mapping import ( + dataset_product_mapping, +) +from copernicusmarine.catalogue_parser.models import ( + CopernicusMarineCatalogue, + CopernicusMarineProduct, + CopernicusMarineProductDataset, + get_version_and_part_from_full_dataset_id, ) from copernicusmarine.core_functions.environment_variables import ( COPERNICUSMARINE_MAX_CONCURRENT_REQUESTS, @@ -27,35 +28,14 @@ get_https_proxy, ) from copernicusmarine.core_functions.utils import ( - CACHE_BASE_DIRECTORY, construct_query_params_for_marine_data_store_monitoring, - datetime_parser, map_reject_none, - next_or_raise_exception, rolling_batch_gather, ) logger = logging.getLogger("copernicus_marine_root_logger") -class _ServiceName(str, Enum): - GEOSERIES = "arco-geo-series" - TIMESERIES = "arco-time-series" - FILES = "original-files" - WMTS = "wmts" - OMI_ARCO = "omi-arco" - STATIC_ARCO = "static-arco" - - -class _ServiceShortName(str, Enum): - GEOSERIES = "geoseries" - TIMESERIES = "timeseries" - FILES = "files" - WMTS = "wmts" - OMI_ARCO = "omi-arco" - STATIC_ARCO = "static-arco" - - MARINE_DATA_STORE_STAC_BASE_URL = ( "https://s3.waw3-1.cloudferro.com/mdl-metadata/metadata" ) @@ -72,393 +52,6 @@ class _ServiceShortName(str, Enum): MAX_CONCURRENT_REQUESTS = int(COPERNICUSMARINE_MAX_CONCURRENT_REQUESTS) -@dataclass(frozen=True) -class _Service: - service_name: _ServiceName - short_name: _ServiceShortName - - def aliases(self) -> List[str]: - return ( - [self.service_name.value, self.short_name.value] - if self.short_name.value != self.service_name.value - else [self.service_name.value] - ) - - def to_json_dict(self): - return { - "service_name": self.service_name.value, - "short_name": self.short_name.value, - } - - -class CopernicusMarineDatasetServiceType(_Service, Enum): - GEOSERIES = _ServiceName.GEOSERIES, _ServiceShortName.GEOSERIES - TIMESERIES = ( - _ServiceName.TIMESERIES, - _ServiceShortName.TIMESERIES, - ) - FILES = _ServiceName.FILES, _ServiceShortName.FILES - WMTS = _ServiceName.WMTS, _ServiceShortName.WMTS - OMI_ARCO = _ServiceName.OMI_ARCO, _ServiceShortName.OMI_ARCO - STATIC_ARCO = _ServiceName.STATIC_ARCO, _ServiceShortName.STATIC_ARCO - - -class CopernicusMarineServiceFormat(str, Enum): - ZARR = "zarr" - SQLITE = "sqlite" - - -def _service_type_from_web_api_string( - name: str, -) -> CopernicusMarineDatasetServiceType: - class WebApi(Enum): - GEOSERIES = "timeChunked" - TIMESERIES = "geoChunked" - FILES = "native" - WMTS = "wmts" - OMI_ARCO = "omi" - STATIC_ARCO = "static" - - web_api_mapping = { - WebApi.GEOSERIES: CopernicusMarineDatasetServiceType.GEOSERIES, - WebApi.TIMESERIES: CopernicusMarineDatasetServiceType.TIMESERIES, - WebApi.FILES: CopernicusMarineDatasetServiceType.FILES, - WebApi.WMTS: CopernicusMarineDatasetServiceType.WMTS, - WebApi.OMI_ARCO: CopernicusMarineDatasetServiceType.OMI_ARCO, - WebApi.STATIC_ARCO: CopernicusMarineDatasetServiceType.STATIC_ARCO, - } - - return next_or_raise_exception( - ( - service_type - for service_web_api, service_type in web_api_mapping.items() - if service_web_api.value == name - ), - ServiceNotHandled(name), - ) - - -class ServiceNotHandled(Exception): - ... - - -VERSION_DEFAULT = "default" -PART_DEFAULT = "default" - - -@dataclass -class CopernicusMarineCoordinates: - coordinates_id: str - units: str - minimum_value: Optional[float] - maximum_value: Optional[float] - step: Optional[float] - values: Optional[list[Union[float, int]]] - chunking_length: Optional[int] - chunk_type: Optional[str] - chunk_reference_coordinate: Optional[int] - chunk_geometric_factor: Optional[int] - - def convert_elevation_to_depth(self): - self.coordinates_id = "depth" - minimum_elevation = self.minimum_value - maximum_elevation = self.maximum_value - if minimum_elevation is not None: - self.maximum_value = -minimum_elevation - else: - self.maximum_value = None - if maximum_elevation is not None: - self.minimum_value = -maximum_elevation - else: - self.minimum_value = None - if self.values is not None: - self.values = [-value for value in self.values] - - -@dataclass -class CopernicusMarineVariable: - short_name: str - standard_name: str - units: str - bbox: Tuple[float, float, float, float] - coordinates: list[CopernicusMarineCoordinates] - - -@dataclass -class CopernicusMarineService: - service_type: CopernicusMarineDatasetServiceType - service_format: Optional[CopernicusMarineServiceFormat] - uri: str - variables: list[CopernicusMarineVariable] - - -@dataclass -class CopernicusMarineVersionPart: - name: str - services: list[CopernicusMarineService] - retired_date: Optional[str] - released_date: Optional[str] - - def get_service_by_service_type( - self, service_type: CopernicusMarineDatasetServiceType - ): - return next( - service - for service in self.services - if service.service_type == service_type - ) - - -@dataclass -class CopernicusMarineDatasetVersion: - label: str - parts: list[CopernicusMarineVersionPart] - - def get_part( - self, force_part: Optional[str] - ) -> CopernicusMarineVersionPart: - wanted_part = force_part or PART_DEFAULT - for part in self.parts: - if part.name == wanted_part: - return part - elif not force_part: - return part - raise dataset_version_part_not_found_exception(self) - - def sort_parts(self) -> tuple[Optional[str], Optional[str]]: - not_released_parts = { - part.name - for part in self.parts - if part.released_date - and datetime_parser(part.released_date) > datetime_parser("now") - } - will_be_retired_parts = { - part.name: datetime_parser(part.retired_date).timestamp() - for part in self.parts - if part.retired_date - } - max_retired_timestamp = 0 - if will_be_retired_parts: - max_retired_timestamp = max(will_be_retired_parts.values()) + 1 - self.parts = sorted( - self.parts, - key=lambda x: ( - x.name in not_released_parts, - max_retired_timestamp - - will_be_retired_parts.get(x.name, max_retired_timestamp), - -(x.name == PART_DEFAULT), - -(x.name == "latest"), # for INSITU datasets - -(x.name == "bathy"), # for STATIC datasets - x.name, - ), - ) - return self.parts[0].released_date, self.parts[0].retired_date - - -class DatasetVersionPartNotFound(Exception): - ... - - -class DatasetVersionNotFound(Exception): - ... - - -@dataclass -class CopernicusMarineProductDataset: - dataset_id: str - dataset_name: str - versions: list[CopernicusMarineDatasetVersion] - - def _seperate_version_and_default( - self, - ) -> Tuple[ - Optional[CopernicusMarineDatasetVersion], - List[CopernicusMarineDatasetVersion], - ]: - default_version = None - versions = [] - for version in self.versions: - if version.label == VERSION_DEFAULT: - default_version = version - else: - versions.append(version) - return default_version, versions - - def get_latest_version_or_raise(self) -> CopernicusMarineDatasetVersion: - default_version, versions = self._seperate_version_and_default() - sorted_versions = sorted(versions, key=lambda x: x.label) - if sorted_versions: - return sorted_versions[-1] - if default_version: - return default_version - raise dataset_version_not_found_exception(self) - - def get_version( - self, force_version: Optional[str] - ) -> CopernicusMarineDatasetVersion: - wanted_version = force_version or VERSION_DEFAULT - for version in self.versions: - if version.label == wanted_version: - return version - elif not force_version: - return version - raise dataset_version_not_found_exception(self) - - def sort_versions(self) -> None: - not_released_versions: set[str] = set() - retired_dates = {} - for version in self.versions: - released_date, retired_date = version.sort_parts() - if released_date and datetime_parser( - released_date - ) > datetime_parser("now"): - not_released_versions.add(version.label) - if retired_date: - retired_dates[version.label] = retired_date - - self.versions = sorted( - self.versions, - key=lambda x: ( - -(x.label in not_released_versions), - retired_dates.get(x.label, "9999-12-31"), - -(x.label == VERSION_DEFAULT), - x.label, - ), - reverse=True, - ) - - -def dataset_version_part_not_found_exception( - version: CopernicusMarineDatasetVersion, -) -> DatasetVersionPartNotFound: - return DatasetVersionPartNotFound( - f"No part found for version {version.label}" - ) - - -def dataset_version_not_found_exception( - dataset: CopernicusMarineProductDataset, -) -> DatasetVersionNotFound: - return DatasetVersionNotFound( - f"No version found for dataset {dataset.dataset_id}" - ) - - -@dataclass -class CopernicusMarineProductProvider: - name: str - roles: list[str] - url: str - email: str - - -@dataclass -class CopernicusMarineProduct: - title: str - product_id: str - thumbnail_url: str - description: str - digital_object_identifier: Optional[str] - sources: List[str] - processing_level: Optional[str] - production_center: str - keywords: dict[str, str] - datasets: list[CopernicusMarineProductDataset] - - -@dataclass -class ProductDatasetParser(ABC): - dataset_id: str - dataset_name: str - versions: list[CopernicusMarineDatasetVersion] - - @abstractmethod - def to_copernicus_marine_dataset( - self, - ) -> CopernicusMarineProductDataset: - ... - - -@dataclass -class ProductParser(ABC): - title: str - product_id: str - thumbnail_url: str - description: str - digital_object_identifier: Optional[str] - sources: List[str] - processing_level: Optional[str] - production_center: str - keywords: dict[str, str] - - -@dataclass -class ProductDatasetFromMarineDataStore(ProductDatasetParser): - def to_copernicus_marine_dataset(self) -> CopernicusMarineProductDataset: - dataset = CopernicusMarineProductDataset( - dataset_id=self.dataset_id, - dataset_name=self.dataset_name, - versions=self.versions, - ) - dataset.sort_versions() - return dataset - - -@dataclass -class ProductFromMarineDataStore(ProductParser): - datasets: list[ProductDatasetFromMarineDataStore] - - def to_copernicus_marine_product(self) -> CopernicusMarineProduct: - return CopernicusMarineProduct( - title=self.title, - product_id=self.product_id, - thumbnail_url=self.thumbnail_url, - description=self.description, - digital_object_identifier=self.digital_object_identifier, - sources=self.sources, - processing_level=self.processing_level, - production_center=self.production_center, - keywords=self.keywords, - datasets=[ - dataset.to_copernicus_marine_dataset() - for dataset in self.datasets - ], - ) - - -@dataclass -class CopernicusMarineCatalogue: - products: list[CopernicusMarineProduct] - - def filter(self, tokens: list[str]): - return filter_catalogue_with_strings(self, tokens) - - def filter_only_official_versions_and_parts(self): - products_to_remove = [] - for product in self.products: - datasets_to_remove = [] - for dataset in product.datasets: - latest_version = dataset.versions[0] - parts_to_remove = [] - for part in latest_version.parts: - if part.released_date and datetime_parser( - part.released_date - ) > datetime_parser("now"): - parts_to_remove.append(part) - for part_to_remove in parts_to_remove: - latest_version.parts.remove(part_to_remove) - if not latest_version.parts: - datasets_to_remove.append(dataset) - else: - dataset.versions = [latest_version] - for dataset_to_remove in datasets_to_remove: - product.datasets.remove(dataset_to_remove) - if not product.datasets: - products_to_remove.append(product) - for product_to_remove in products_to_remove: - self.products.remove(product_to_remove) - - class CatalogParserConnection: def __init__(self, proxy: Optional[str] = None) -> None: self.proxy = proxy @@ -500,243 +93,132 @@ def _retry_policy(self, info: RetryInfo) -> RetryPolicyStrategy: return info.fails >= self.__max_retries, info.fails * self.__sleep_time -def _construct_copernicus_marine_service( - stac_service_name, stac_asset, datacube -) -> Optional[CopernicusMarineService]: - try: - service_uri = stac_asset.get_absolute_href() - service_type = _service_type_from_web_api_string(stac_service_name) - service_format = None - admp_in_preparation = datacube.properties.get("admp_in_preparation") - if stac_asset.media_type and "zarr" in stac_asset.media_type: - service_format = CopernicusMarineServiceFormat.ZARR - elif stac_asset.media_type and "sqlite3" in stac_asset.media_type: - service_format = CopernicusMarineServiceFormat.SQLITE - - if not service_uri.endswith("/"): - if admp_in_preparation and ( - service_type == CopernicusMarineDatasetServiceType.GEOSERIES - or service_type - == CopernicusMarineDatasetServiceType.TIMESERIES - ): - return None - else: - return CopernicusMarineService( - service_type=service_type, - uri=service_uri, - variables=_get_variables(datacube, stac_asset), - service_format=service_format, - ) - return None - except ServiceNotHandled as service_not_handled: - log_exception_debug(service_not_handled) +async def get_dataset_metadata( + dataset_id: str, staging: bool +) -> Optional[CopernicusMarineProductDataset]: + connection = CatalogParserConnection() + product_id = dataset_product_mapping[dataset_id] # here mds mapping + root_url = ( + MARINE_DATA_STORE_STAC_BASE_URL + if not staging + else MARINE_DATA_STORE_STAC_BASE_URL_STAGING + ) + url = f"{root_url}/{product_id}/product.stac.json" + product_json = await connection.get_json_file(url) + product_collection = pystac.Collection.from_dict(product_json) + product_datasets_metadata_links = product_collection.get_item_links() + datasets_metadata_links = [ + dataset_metadata_link + for dataset_metadata_link in product_datasets_metadata_links + if dataset_id in dataset_metadata_link.href + ] + if not datasets_metadata_links: return None - - -def _get_versions_from_marine_datastore( - datacubes: List[pystac.Item], -) -> List[CopernicusMarineDatasetVersion]: - copernicus_marine_dataset_versions: List[ - CopernicusMarineDatasetVersion - ] = [] - - datacubes_by_version = groupby( - datacubes, - key=lambda datacube: get_version_and_part_from_full_dataset_id( - datacube.id - )[1], + # TODO: check if we gain a lot of time by doing a gather here + # if not don't forget to add a retry policy + + dataset_jsons: list[dict] = await asyncio.gather( + *[ + connection.get_json_file(f"{root_url}/{product_id}/{link.href}") + for link in datasets_metadata_links + ] ) - for dataset_version, datacubes in datacubes_by_version: # type: ignore - parts = _get_parts(datacubes) - - if parts: - version = CopernicusMarineDatasetVersion( - label=dataset_version, - parts=parts, - ) - copernicus_marine_dataset_versions.append(version) - - return copernicus_marine_dataset_versions - - -def _get_parts( - datacubes: List[pystac.Item], -) -> List[CopernicusMarineVersionPart]: - parts: List[CopernicusMarineVersionPart] = [] - for datacube in datacubes: - released_date = datacube.properties.get("admp_released_date") - retired_date = datacube.properties.get("admp_retired_date") - if retired_date and datetime_parser(retired_date) < datetime_parser( - "now" - ): - continue - - services = _get_services(datacube) - _, _, part = get_version_and_part_from_full_dataset_id(datacube.id) - - if services: - parts.append( - CopernicusMarineVersionPart( - name=part, - services=services, - retired_date=retired_date, - released_date=released_date, - ) - ) - - if parts: - return parts - return [] - - -def _get_services( - datacube: pystac.Item, -) -> list[CopernicusMarineService]: - stac_assets_dict = datacube.get_assets() - return [ - dataset_service - for stac_service_name, stac_asset in stac_assets_dict.items() - if ( - dataset_service := _construct_copernicus_marine_service( - stac_service_name, stac_asset, datacube - ) - ) - is not None + await connection.close() + dataset_items = [ + dataset_item + for dataset_json in dataset_jsons + if (dataset_item := _parse_dataset_json_to_pystac_item(dataset_json)) ] + return _parse_and_sort_dataset_items(dataset_items) -def _format_arco_data_metadata_producer_valid_start_date( - arco_data_metadata_producer_valid_start_date: str, - to_timestamp: bool = False, -) -> Union[str, int]: - if to_timestamp: - return int( - datetime_parser( - arco_data_metadata_producer_valid_start_date.split(".")[0] - ).timestamp() - * 1000 - ) - return arco_data_metadata_producer_valid_start_date.split(".")[0] - - -def _get_variables( - stac_dataset: pystac.Item, - stac_asset: pystac.Asset, -) -> list[CopernicusMarineVariable]: - bbox = stac_dataset.bbox - return [ - CopernicusMarineVariable( - short_name=var_cube["id"], - standard_name=var_cube["standardName"], - units=var_cube.get("unit") or "", - bbox=bbox, - coordinates=_get_coordinates( - var_cube["id"], - stac_asset, - stac_dataset.properties.get("admp_valid_start_date"), - ) - or [], +def _parse_dataset_json_to_pystac_item( + metadate_json: dict, +) -> Optional[pystac.Item]: + try: + return pystac.Item.from_dict(metadate_json) + except pystac.STACError as exception: + message = ( + "Invalid Item: If datetime is None, a start_datetime " + + "and end_datetime must be supplied." ) - for var_cube in stac_dataset.properties["cube:variables"].values() - ] + if exception.args[0] != message: + logger.error(exception) + raise pystac.STACError(exception.args) + return None -def _get_coordinates( - variable_id: str, - stac_asset: pystac.Asset, - arco_data_metadata_producer_valid_start_date: Optional[str], -) -> Optional[list[CopernicusMarineCoordinates]]: - extra_fields_asset = stac_asset.extra_fields - dimensions = extra_fields_asset.get("viewDims") - if dimensions: - coordinates = [] - for dimension, dimension_metadata in dimensions.items(): - coordinates_info = dimension_metadata.get("coords", {}) - if ( - arco_data_metadata_producer_valid_start_date - and dimension == "time" - ): - minimum_value = ( - _format_arco_data_metadata_producer_valid_start_date( - arco_data_metadata_producer_valid_start_date, - to_timestamp=isinstance( - coordinates_info.get("min"), int - ), - ) - ) - else: - minimum_value = coordinates_info.get("min") - chunking_length = dimension_metadata.get("chunkLen") - if isinstance(chunking_length, dict): - chunking_length = chunking_length.get(variable_id) - coordinate = CopernicusMarineCoordinates( - coordinates_id=( - "depth" if dimension == "elevation" else dimension - ), - units=dimension_metadata.get("units") or "", - minimum_value=minimum_value, # type: ignore - maximum_value=coordinates_info.get("max"), - step=coordinates_info.get("step"), - values=coordinates_info.get("values"), - chunking_length=chunking_length, - chunk_type=dimension_metadata.get("chunkType"), - chunk_reference_coordinate=dimension_metadata.get( - "chunkRefCoord" - ), - chunk_geometric_factor=dimension_metadata.get( - "chunkGeometricFactor", {} - ).get(variable_id), - ) - if dimension == "elevation": - coordinate.convert_elevation_to_depth() - coordinates.append(coordinate) - return coordinates - else: +def _parse_product_json_to_pystac_collection( + metadata_json: dict, +) -> Optional[pystac.Collection]: + try: + return pystac.Collection.from_dict(metadata_json) + except KeyError as exception: + messages = ["spatial", "temporal"] + if exception.args[0] not in messages: + logger.error(exception) return None -def _construct_marine_data_store_dataset( - datacubes_by_id: List, -) -> Optional[ProductDatasetFromMarineDataStore]: - dataset_id = datacubes_by_id[0] - datacubes = list(datacubes_by_id[1]) - dataset_name = ( - datacubes[0].properties["title"] if len(datacubes) == 1 else dataset_id +def _parse_and_sort_dataset_items( + dataset_items: list[pystac.Item], +) -> Optional[CopernicusMarineProductDataset]: + """ + Return all dataset metadata parsed and sorted. + The first version and part are the default. + """ + dataset_item_example = dataset_items[0] + dataset_id, _, _ = get_version_and_part_from_full_dataset_id( + dataset_item_example.id ) - if datacubes: - versions = _get_versions_from_marine_datastore(datacubes) - if versions: - return ProductDatasetFromMarineDataStore( - dataset_id=dataset_id, - dataset_name=dataset_name, - versions=versions, - ) - return None + dataset_part_version_merged = CopernicusMarineProductDataset( + dataset_id=dataset_id, + dataset_name=dataset_item_example.properties.get("title", dataset_id), + versions=[], + ) + dataset_part_version_merged.parse_dataset_metadata_items(dataset_items) + + if dataset_part_version_merged.versions == []: + return None + + dataset_part_version_merged.sort_versions() + return dataset_part_version_merged def _construct_marine_data_store_product( stac_tuple: Tuple[pystac.Collection, List[pystac.Item]], -) -> ProductFromMarineDataStore: +) -> CopernicusMarineProduct: stac_product, stac_datasets = stac_tuple stac_datasets_sorted = sorted(stac_datasets, key=lambda x: x.id) - datacubes_by_id = groupby( + dataset_items_by_dataset_id = groupby( stac_datasets_sorted, key=lambda x: get_version_and_part_from_full_dataset_id(x.id)[0], ) - datasets = map( - _construct_marine_data_store_dataset, # type: ignore - datacubes_by_id, # type: ignore - ) + datasets = [ + dataset_metadata + for _, dataset_items in dataset_items_by_dataset_id + if ( + dataset_metadata := _parse_and_sort_dataset_items( + list(dataset_items) + ) + ) + ] production_center = [ provider.name for provider in stac_product.providers or [] - if "producer" in provider.roles + if provider.roles and "producer" in provider.roles ] production_center_name = production_center[0] if production_center else "" + if stac_product.assets: + thumbnail = stac_product.assets.get("thumbnail") + if thumbnail: + thumbnail_url = thumbnail.get_absolute_href() + else: + thumbnail_url = None thumbnail = stac_product.assets and stac_product.assets.get("thumbnail") digital_object_identifier = ( stac_product.extra_fields.get("sci:doi", None) @@ -748,20 +230,17 @@ def _construct_marine_data_store_product( stac_product, "processingLevel" ) - return ProductFromMarineDataStore( + return CopernicusMarineProduct( title=stac_product.title or stac_product.id, product_id=stac_product.id, - thumbnail_url=thumbnail.get_absolute_href() if thumbnail else "", + thumbnail_url=thumbnail_url or "", description=stac_product.description, digital_object_identifier=digital_object_identifier, sources=sources, processing_level=processing_level, production_center=production_center_name, keywords=stac_product.keywords, - datasets=sorted( - [dataset for dataset in datasets if dataset], - key=lambda dataset: dataset.dataset_id, - ), + datasets=datasets, ) @@ -776,7 +255,7 @@ def _get_stac_product_property( return properties.get(property_key) -async def async_fetch_items_from_collection( +async def async_fetch_dataset_items( root_url: str, connection: CatalogParserConnection, collection: pystac.Collection, @@ -787,39 +266,29 @@ async def async_fetch_items_from_collection( logger.warning(f"Invalid Item, no owner for: {link.href}") continue url = root_url + "/" + link.owner.id + "/" + link.href - try: - item_json = await connection.get_json_file(url) - items.append(pystac.Item.from_dict(item_json)) - except pystac.STACError as exception: - message = ( - "Invalid Item: If datetime is None, a start_datetime " - + "and end_datetime must be supplied." - ) - if exception.args[0] != message: - logger.error(exception) - raise pystac.STACError(exception.args) + item_json = await connection.get_json_file(url) + item = _parse_dataset_json_to_pystac_item(item_json) + if item: + items.append(item) return items async def async_fetch_collection( - root_url: str, connection: CatalogParserConnection, url: str + root_url: str, + connection: CatalogParserConnection, + url: str, ) -> Optional[Tuple[pystac.Collection, List[pystac.Item]]]: json_collection = await connection.get_json_file(url) - try: - collection = pystac.Collection.from_dict(json_collection) - items = await async_fetch_items_from_collection( + collection = _parse_product_json_to_pystac_collection(json_collection) + if collection: + items = await async_fetch_dataset_items( root_url, connection, collection ) return (collection, items) - - except KeyError as exception: - messages = ["spatial", "temporal"] - if exception.args[0] not in messages: - logger.error(exception) - return None + return None -async def async_fetch_childs( +async def async_fetch_product_items( root_url: str, connection: CatalogParserConnection, child_links: List[pystac.Link], @@ -835,10 +304,10 @@ async def async_fetch_childs( ) -async def async_fetch_catalog( +async def async_fetch_all_products_items( connection: CatalogParserConnection, - staging: bool = False, -) -> Iterator[pystac.Collection]: + staging: bool, +) -> Iterator[Optional[tuple[pystac.Collection, list[pystac.Item]]]]: catalog_root_url = ( MARINE_DATA_STORE_STAC_ROOT_CATALOG_URL if not staging @@ -853,87 +322,47 @@ async def async_fetch_catalog( if not staging else (MARINE_DATA_STORE_STAC_BASE_URL_STAGING) ) - childs = await async_fetch_childs(root_url, connection, child_links) + childs = await async_fetch_product_items(root_url, connection, child_links) return childs -def _retrieve_marine_data_store_products( - connection: CatalogParserConnection, - staging: bool = False, -) -> list[ProductFromMarineDataStore]: - nest_asyncio.apply() - loop = asyncio.get_event_loop() - marine_data_store_root_collections = loop.run_until_complete( - async_fetch_catalog(connection=connection, staging=staging) - ) - - products = map_reject_none( - _construct_marine_data_store_product, - marine_data_store_root_collections, - ) - - return list(products) - - def parse_catalogue( - no_metadata_cache: bool, disable_progress_bar: bool, staging: bool = False, ) -> CopernicusMarineCatalogue: logger.debug("Parsing catalogue...") - try: - catalog = _parse_catalogue( - ignore_cache=no_metadata_cache, - _versions=package_version("copernicusmarine"), - disable_progress_bar=disable_progress_bar, - staging=staging, - ) - except ValueError as e: - logger.debug(f"Error while parsing catalogue: {e}") - logger.debug( - "Now retrying without cache. If the problem with " - "the cache persists, try running " - "copernicusmarine describe --overwrite-metadata-cache" - ) - catalog = _parse_catalogue( - ignore_cache=True, - _versions=package_version("copernicusmarine"), - disable_progress_bar=disable_progress_bar, - staging=staging, - ) - logger.debug("Catalogue parsed") - return catalog - - -@cachier(cache_dir=CACHE_BASE_DIRECTORY, stale_after=timedelta(hours=24)) -def _parse_catalogue( - _versions: str, # force cachier to overwrite cache in case of version update - disable_progress_bar: bool, - staging: bool = False, -) -> CopernicusMarineCatalogue: progress_bar = tqdm( - total=3, desc="Fetching catalog", disable=disable_progress_bar + total=2, desc="Fetching catalog", disable=disable_progress_bar ) - connection = CatalogParserConnection() - marine_data_store_products = _retrieve_marine_data_store_products( - connection=connection, staging=staging + connection = CatalogParserConnection() + nest_asyncio.apply() + loop = asyncio.get_event_loop() + marine_data_store_root_collections = loop.run_until_complete( + async_fetch_all_products_items(connection=connection, staging=staging) ) progress_bar.update() - products_merged: List[CopernicusMarineProduct] = [ - marine_data_store_product.to_copernicus_marine_product() - for marine_data_store_product in marine_data_store_products - if marine_data_store_product.datasets + products_metadata = [ + product_metadata + for product_item in marine_data_store_root_collections + if product_item + and ( + ( + product_metadata := _construct_marine_data_store_product( + product_item + ) + ).datasets + ) ] - products_merged.sort(key=lambda x: x.product_id) - progress_bar.update() + products_metadata.sort(key=lambda x: x.product_id) - full_catalog = CopernicusMarineCatalogue(products=products_merged) + full_catalog = CopernicusMarineCatalogue(products=products_metadata) - progress_bar.update() - asyncio.run(connection.close()) + loop.run_until_complete(connection.close()) + progress_bar.update() + logger.debug("Catalogue parsed") return full_catalog @@ -947,50 +376,11 @@ class DistinctDatasetVersionPart: stac_items_values: Optional[Dict] -REGEX_PATTERN_DATE_YYYYMM = r"[12]\d{3}(0[1-9]|1[0-2])" -PART_SEPARATOR = "--ext--" - - -def get_version_and_part_from_full_dataset_id( - full_dataset_id: str, -) -> Tuple[str, str, str]: - if PART_SEPARATOR in full_dataset_id: - name_with_maybe_version, part = full_dataset_id.split(PART_SEPARATOR) - else: - name_with_maybe_version = full_dataset_id - part = PART_DEFAULT - pattern = rf"^(.*?)(?:_({REGEX_PATTERN_DATE_YYYYMM}))?$" - match = re.match(pattern, name_with_maybe_version) - if match: - dataset_name = match.group(1) - version = match.group(2) or VERSION_DEFAULT - else: - raise Exception(f"Could not parse dataset id: {full_dataset_id}") - return dataset_name, version, part - - # --------------------------------------- # --- Utils function on any catalogue --- # --------------------------------------- -def get_product_from_url( - catalogue: CopernicusMarineCatalogue, dataset_url: str -) -> CopernicusMarineProduct: - """ - Return the product object, with its dataset list filtered - """ - filtered_catalogue = filter_catalogue_with_strings( - catalogue, [dataset_url] - ) - if filtered_catalogue is None: - error = TypeError("filtered catalogue is empty") - raise error - if isinstance(filtered_catalogue, CopernicusMarineCatalogue): - return filtered_catalogue.products[0] - return filtered_catalogue["products"][0] - - def filter_catalogue_with_strings( catalogue: CopernicusMarineCatalogue, tokens: list[str] ) -> dict[str, Any]: diff --git a/copernicusmarine/catalogue_parser/dataset_product_mapping.py b/copernicusmarine/catalogue_parser/dataset_product_mapping.py new file mode 100644 index 00000000..d3724b89 --- /dev/null +++ b/copernicusmarine/catalogue_parser/dataset_product_mapping.py @@ -0,0 +1,1059 @@ +dataset_product_mapping = { + "antarctic_omi_si_extent": "ANTARCTIC_OMI_SI_extent", + "antarctic_omi_si_extent_obs": "ANTARCTIC_OMI_SI_extent_obs", + "cmems_mod_arc_bgc_anfc_ecosmo_P1D-m": "ARCTIC_ANALYSISFORECAST_BGC_002_004", + "cmems_mod_arc_bgc_anfc_ecosmo_P1M-m": "ARCTIC_ANALYSISFORECAST_BGC_002_004", + "cmems_mod_arc_phy_anfc_6km_detided_P1D-m": "ARCTIC_ANALYSISFORECAST_PHY_002_001", + "cmems_mod_arc_phy_anfc_6km_detided_P1M-m": "ARCTIC_ANALYSISFORECAST_PHY_002_001", + "cmems_mod_arc_phy_anfc_6km_detided_PT1H-i": "ARCTIC_ANALYSISFORECAST_PHY_002_001", + "cmems_mod_arc_phy_anfc_6km_detided_PT6H-m": "ARCTIC_ANALYSISFORECAST_PHY_002_001", + "cmems_mod_arc_phy_anfc_nextsim_P1M-m": "ARCTIC_ANALYSISFORECAST_PHY_ICE_002_011", + "cmems_mod_arc_phy_anfc_nextsim_hm": "ARCTIC_ANALYSISFORECAST_PHY_ICE_002_011", + "dataset-topaz6-arc-15min-3km-be": "ARCTIC_ANALYSISFORECAST_PHY_TIDE_002_015", + "dataset-wam-arctic-1hr3km-be": "ARCTIC_ANALYSIS_FORECAST_WAV_002_014", + "cmems_mod_arc_bgc_my_ecosmo_P1D-m": "ARCTIC_MULTIYEAR_BGC_002_005", + "cmems_mod_arc_bgc_my_ecosmo_P1M": "ARCTIC_MULTIYEAR_BGC_002_005", + "cmems_mod_arc_bgc_my_ecosmo_P1Y": "ARCTIC_MULTIYEAR_BGC_002_005", + "cmems_mod_arc_phy_my_topaz4_P1D-m": "ARCTIC_MULTIYEAR_PHY_002_003", + "cmems_mod_arc_phy_my_topaz4_P1M": "ARCTIC_MULTIYEAR_PHY_002_003", + "cmems_mod_arc_phy_my_topaz4_P1Y": "ARCTIC_MULTIYEAR_PHY_002_003", + "cmems_mod_arc_wav_my_3km-climatology_P1M-m": "ARCTIC_MULTIYEAR_WAV_002_013", + "cmems_mod_arc_wav_my_3km_PT1H-i": "ARCTIC_MULTIYEAR_WAV_002_013", + "arctic_omi_si_transport_nordicseas": "ARCTIC_OMI_SI_Transport_NordicSeas", + "arctic_omi_si_extent": "ARCTIC_OMI_SI_extent", + "arctic_omi_si_extent_obs": "ARCTIC_OMI_SI_extent_obs", + "arctic_omi_tempsal_fwc": "ARCTIC_OMI_TEMPSAL_FWC", + "cmems_mod_bal_bgc-pp_anfc_P1D-i": "BALTICSEA_ANALYSISFORECAST_BGC_003_007", + "cmems_mod_bal_bgc_anfc_P1D-m": "BALTICSEA_ANALYSISFORECAST_BGC_003_007", + "cmems_mod_bal_bgc_anfc_P1M-m": "BALTICSEA_ANALYSISFORECAST_BGC_003_007", + "cmems_mod_bal_bgc_anfc_static": "BALTICSEA_ANALYSISFORECAST_BGC_003_007", + "cmems_mod_bal_phy-cur_anfc_detided_P1D-m": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_phy-ssh_anfc_detided_P1D-m": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_phy_anfc_P1D-m": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_phy_anfc_P1M-m": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_phy_anfc_PT15M-i": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_phy_anfc_PT1H-i": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_phy_anfc_static": "BALTICSEA_ANALYSISFORECAST_PHY_003_006", + "cmems_mod_bal_wav_anfc_PT1H-i": "BALTICSEA_ANALYSISFORECAST_WAV_003_010", + "cmems_mod_bal_wav_anfc_static": "BALTICSEA_ANALYSISFORECAST_WAV_003_010", + "cmems_mod_bal_bgc_my_P1D-m": "BALTICSEA_MULTIYEAR_BGC_003_012", + "cmems_mod_bal_bgc_my_P1M-m": "BALTICSEA_MULTIYEAR_BGC_003_012", + "cmems_mod_bal_bgc_my_P1Y-m": "BALTICSEA_MULTIYEAR_BGC_003_012", + "cmems_mod_bal_bgc_my_static": "BALTICSEA_MULTIYEAR_BGC_003_012", + "cmems_mod_bal_phy_my_P1D-m": "BALTICSEA_MULTIYEAR_PHY_003_011", + "cmems_mod_bal_phy_my_P1M-m": "BALTICSEA_MULTIYEAR_PHY_003_011", + "cmems_mod_bal_phy_my_P1Y-m": "BALTICSEA_MULTIYEAR_PHY_003_011", + "cmems_mod_bal_phy_my_static": "BALTICSEA_MULTIYEAR_PHY_003_011", + "cmems_mod_bal_wav_my_2km-climatology_P1M-m": "BALTICSEA_REANALYSIS_WAV_003_015", + "cmems_mod_bal_wav_my_static": "BALTICSEA_REANALYSIS_WAV_003_015", + "dataset-bal-reanalysis-wav-hourly": "BALTICSEA_REANALYSIS_WAV_003_015", + "baltic_omi_health_codt_volume": "BALTIC_OMI_HEALTH_codt_volume", + "baltic_omi_ohc_area_averaged_anomalies": "BALTIC_OMI_OHC_area_averaged_anomalies", + "baltic_omi_si_extent": "BALTIC_OMI_SI_extent", + "baltic_omi_si_extent_yday": "BALTIC_OMI_SI_extent", + "baltic_omi_si_volume": "BALTIC_OMI_SI_volume", + "baltic_omi_si_volume_yday": "BALTIC_OMI_SI_volume", + "baltic_omi_tempsal_Stz_area_averaged_trend": "BALTIC_OMI_TEMPSAL_Stz_trend", + "baltic_omi_tempsal_Ttz_area_averaged_trend": "BALTIC_OMI_TEMPSAL_Ttz_trend", + "baltic_omi_wmhe_mbi_bottom_salinity_arkona_bornholm": "BALTIC_OMI_WMHE_mbi_bottom_salinity_arkona_bornholm", + "baltic_omi_wmhe_mbi_sto2tz_gotland": "BALTIC_OMI_WMHE_mbi_sto2tz_gotland", + "cmems_mod_blk_bgc-bio_anfc_3km_P1D-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-bio_anfc_3km_P1M-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-car_anfc_3km_P1D-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-car_anfc_3km_P1M-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-co2_anfc_3km_P1D-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-co2_anfc_3km_P1M-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-co2_anfc_3km_PT1H-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-nut_anfc_3km_P1D-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-nut_anfc_3km_P1M-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-opt_anfc_3km_P1D-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-opt_anfc_3km_P1M-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-pft_anfc_3km_P1D-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc-pft_anfc_3km_P1M-m": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_bgc_anfc_3km_static": "BLKSEA_ANALYSISFORECAST_BGC_007_010", + "cmems_mod_blk_phy-cur_anfc_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-cur_anfc_2.5km_P1M-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-cur_anfc_2.5km_PT15M-i": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-cur_anfc_2.5km_PT1H-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-cur_anfc_detided_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-cur_anfc_mrm-500m_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-cur_anfc_mrm-500m_PT1H-i": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-mld_anfc_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-mld_anfc_2.5km_P1M-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-mld_anfc_2.5km_PT1H-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-sal_anfc_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-sal_anfc_2.5km_P1M-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-sal_anfc_2.5km_PT1H-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-sal_anfc_mrm-500m_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-sal_anfc_mrm-500m_PT1H-i": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_2.5km_P1M-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_2.5km_PT15M-i": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_2.5km_PT1H-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_detided_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_mrm-500m_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-ssh_anfc_mrm-500m_PT1H-i": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-tem_anfc_2.5km_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-tem_anfc_2.5km_P1M-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-tem_anfc_2.5km_PT1H-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-tem_anfc_mrm-500m_P1D-m": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy-tem_anfc_mrm-500m_PT1H-i": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy_anfc_2.5km_static": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_phy_anfc_mrm-500m_static": "BLKSEA_ANALYSISFORECAST_PHY_007_001", + "cmems_mod_blk_wav_anfc_2.5km_PT1H-i": "BLKSEA_ANALYSISFORECAST_WAV_007_003", + "cmems_mod_blk_wav_anfc_2.5km_static": "BLKSEA_ANALYSISFORECAST_WAV_007_003", + "cmems_mod_blk_bgc-bio_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-bio_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-bio_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-bio_my_2.5km_climatology_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-bio_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-car_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-car_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-car_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-car_my_2.5km_climatology_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-car_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-co2_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-co2_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-co2_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-co2_my_2.5km_climatology_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-co2_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-nut_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-nut_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-nut_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-nut_my_2.5km_climatology_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-nut_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-plankton_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-plankton_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-plankton_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-plankton_my_2.5km_climatology_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc-plankton_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_bgc_my_2.5km_static": "BLKSEA_MULTIYEAR_BGC_007_005", + "cmems_mod_blk_phy-cur_my_2.5km-climatology_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-cur_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-cur_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-cur_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-cur_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-mld_my_2.5km-climatology_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-mld_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-mld_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-mld_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-mld_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-sal_my_2.5km-climatology_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-sal_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-sal_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-sal_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-sal_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-ssh_my_2.5km-climatology_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-ssh_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-ssh_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-ssh_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-ssh_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-tem_my_2.5km-climatology_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-tem_my_2.5km_P1D-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-tem_my_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-tem_my_2.5km_P1Y-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy-tem_myint_2.5km_P1M-m": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_phy_my_2.5km_static": "BLKSEA_MULTIYEAR_PHY_007_004", + "cmems_mod_blk_wav_my_2.5km-climatology_PT1M-m": "BLKSEA_MULTIYEAR_WAV_007_006", + "cmems_mod_blk_wav_my_2.5km_PT1H-i": "BLKSEA_MULTIYEAR_WAV_007_006", + "cmems_mod_blk_wav_my_2.5km_static": "BLKSEA_MULTIYEAR_WAV_007_006", + "cmems_mod_blk_wav_myint_2.5km_PT1H-i": "BLKSEA_MULTIYEAR_WAV_007_006", + "blksea_omi_health_oxygen_trend_annual": "BLKSEA_OMI_HEALTH_oxygen_trend", + "blksea_omi_health_oxygen_trend_monthly": "BLKSEA_OMI_HEALTH_oxygen_trend", + "blksea_omi_seastate_extreme_var_swh_mean_and_anomaly": "BLKSEA_OMI_SEASTATE_extreme_var_swh_mean_and_anomaly", + "blksea_omi_tempsal_extreme_var_temp_mean_and_anomaly": "BLKSEA_OMI_TEMPSAL_extreme_var_temp_mean_and_anomaly", + "blksea_omi_tempsal_sst_area_averaged_anomalies": "BLKSEA_OMI_TEMPSAL_sst_area_averaged_anomalies", + "blksea_omi_tempsal_sst_trend": "BLKSEA_OMI_TEMPSAL_sst_trend", + "cmems_mod_glo_bgc-bio_anfc_0.25deg_P1D-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-bio_anfc_0.25deg_P1M-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-car_anfc_0.25deg_P1D-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-car_anfc_0.25deg_P1M-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-co2_anfc_0.25deg_P1D-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-co2_anfc_0.25deg_P1M-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-nut_anfc_0.25deg_P1D-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-nut_anfc_0.25deg_P1M-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-optics_anfc_0.25deg_P1D-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-optics_anfc_0.25deg_P1M-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-pft_anfc_0.25deg_P1D-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc-pft_anfc_0.25deg_P1M-m": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_bgc_anfc_0.25deg_static": "GLOBAL_ANALYSISFORECAST_BGC_001_028", + "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-cur_anfc_0.083deg_P1M-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-cur_anfc_0.083deg_PT6H-i": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-so_anfc_0.083deg_P1D-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-so_anfc_0.083deg_P1M-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-so_anfc_0.083deg_PT6H-i": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1M-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-thetao_anfc_0.083deg_PT6H-i": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-wcur_anfc_0.083deg_P1D-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-wcur_anfc_0.083deg_P1M-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy_anfc_0.083deg-climatology-uncertainty_P1M-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy_anfc_0.083deg_P1D-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy_anfc_0.083deg_P1M-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy_anfc_0.083deg_PT1H-m": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy_anfc_0.083deg_static": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy_anfc_merged-uv_PT1H-i": "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_wav_anfc_0.083deg_PT3H-i": "GLOBAL_ANALYSISFORECAST_WAV_001_027", + "cmems_mod_wav_anfc_0.083deg_static": "GLOBAL_ANALYSISFORECAST_WAV_001_027", + "cmems_mod_glo_bgc_my_0.25deg_P1D-m": "GLOBAL_MULTIYEAR_BGC_001_029", + "cmems_mod_glo_bgc_my_0.25deg_P1M-m": "GLOBAL_MULTIYEAR_BGC_001_029", + "cmems_mod_glo_bgc_my_0.25deg_static": "GLOBAL_MULTIYEAR_BGC_001_029", + "cmems_mod_glo_bgc_myint_0.25deg_P1D-m": "GLOBAL_MULTIYEAR_BGC_001_029", + "cmems_mod_glo_bgc_myint_0.25deg_P1M-m": "GLOBAL_MULTIYEAR_BGC_001_029", + "cmems_mod_glo_bgc_my_0.083deg-lmtl-Fphy_PT1D-i": "GLOBAL_MULTIYEAR_BGC_001_033", + "cmems_mod_glo_bgc_my_0.083deg-lmtl_PT1D-i": "GLOBAL_MULTIYEAR_BGC_001_033", + "cmems_mod_glo_phy_my_0.083deg-climatology_P1M-m": "GLOBAL_MULTIYEAR_PHY_001_030", + "cmems_mod_glo_phy_my_0.083deg_P1D-m": "GLOBAL_MULTIYEAR_PHY_001_030", + "cmems_mod_glo_phy_my_0.083deg_P1M-m": "GLOBAL_MULTIYEAR_PHY_001_030", + "cmems_mod_glo_phy_my_0.083deg_static": "GLOBAL_MULTIYEAR_PHY_001_030", + "cmems_mod_glo_phy_myint_0.083deg_P1D-m": "GLOBAL_MULTIYEAR_PHY_001_030", + "cmems_mod_glo_phy_myint_0.083deg_P1M-m": "GLOBAL_MULTIYEAR_PHY_001_030", + "cmems_mod_glo_phy-all_my_0.25deg_P1D-m": "GLOBAL_MULTIYEAR_PHY_ENS_001_031", + "cmems_mod_glo_phy-all_my_0.25deg_P1M-m": "GLOBAL_MULTIYEAR_PHY_ENS_001_031", + "cmems_mod_glo_phy-mnstd_my_0.25deg_P1D-m": "GLOBAL_MULTIYEAR_PHY_ENS_001_031", + "cmems_mod_glo_phy-mnstd_my_0.25deg_P1M-m": "GLOBAL_MULTIYEAR_PHY_ENS_001_031", + "cmems_mod_glo_wav_my_0.2deg-climatology_P1M-m": "GLOBAL_MULTIYEAR_WAV_001_032", + "cmems_mod_glo_wav_my_0.2deg_PT3H-i": "GLOBAL_MULTIYEAR_WAV_001_032", + "cmems_mod_glo_wav_my_0.2deg_static": "GLOBAL_MULTIYEAR_WAV_001_032", + "cmems_mod_glo_wav_myint_0.2deg_PT3H-i": "GLOBAL_MULTIYEAR_WAV_001_032", + "global_omi_climate-variability_nino34_tzt_anom": "GLOBAL_OMI_CLIMVAR_enso_Tzt_anomaly", + "global_omi_climate-variability_nino34_sst_anom": "GLOBAL_OMI_CLIMVAR_enso_sst_area_averaged_anomalies", + "global_omi_health_carbon_co2_flux_integrated": "GLOBAL_OMI_HEALTH_carbon_co2_flux_integrated", + "global_omi_health_carbon_ph_area_averaged": "GLOBAL_OMI_HEALTH_carbon_ph_area_averaged", + "global_omi_health_carbon_ph_trend": "GLOBAL_OMI_HEALTH_carbon_ph_trend", + "global_omi_natlantic_amoc_26N_profile": "GLOBAL_OMI_NATLANTIC_amoc_26N_profile", + "global_omi_natlantic_amoc_max26N_timeseries": "GLOBAL_OMI_NATLANTIC_amoc_max26N_timeseries", + "global_omi_ohc_area_averaged_anomalies_0_2000": "GLOBAL_OMI_OHC_area_averaged_anomalies_0_2000", + "global_omi_ohc_area_averaged_anomalies_0_300": "GLOBAL_OMI_OHC_area_averaged_anomalies_0_300", + "global_omi_ohc_area_averaged_anomalies_0_700": "GLOBAL_OMI_OHC_area_averaged_anomalies_0_700", + "global_omi_ohc_trend": "GLOBAL_OMI_OHC_trend", + "global_omi_sl_thsl_area_averaged_anomalies_0_2000": "GLOBAL_OMI_SL_thsl_area_averaged_anomalies_0_2000", + "global_omi_sl_thsl_area_averaged_anomalies_0_700": "GLOBAL_OMI_SL_thsl_area_averaged_anomalies_0_700", + "global_omi_sl_thsl_trend": "GLOBAL_OMI_SL_thsl_trend", + "global_omi_tempsal_tyz_trend": "GLOBAL_OMI_TEMPSAL_Tyz_trend", + "global_omi_tempsal_sst_area_averaged_anomalies": "GLOBAL_OMI_TEMPSAL_sst_area_averaged_anomalies", + "global_omi_tempsal_sst_trend": "GLOBAL_OMI_TEMPSAL_sst_trend", + "global_omi_wmhe_heattrp": "GLOBAL_OMI_WMHE_heattrp", + "global_omi_wmhe_northward_mht": "GLOBAL_OMI_WMHE_northward_mht", + "global_omi_wmhe_voltrp": "GLOBAL_OMI_WMHE_voltrp", + "cmems_mod_ibi_bgc_anfc_0.027deg-3D_P1D-m": "IBI_ANALYSISFORECAST_BGC_005_004", + "cmems_mod_ibi_bgc_anfc_0.027deg-3D_P1M-m": "IBI_ANALYSISFORECAST_BGC_005_004", + "cmems_mod_ibi_bgc_anfc_0.027deg-3D_static": "IBI_ANALYSISFORECAST_BGC_005_004", + "cmems_mod_ibi_phy_anfc_0.027deg-2D_PT15M-i": "IBI_ANALYSISFORECAST_PHY_005_001", + "cmems_mod_ibi_phy_anfc_0.027deg-2D_PT1H-m": "IBI_ANALYSISFORECAST_PHY_005_001", + "cmems_mod_ibi_phy_anfc_0.027deg-3D_P1D-m": "IBI_ANALYSISFORECAST_PHY_005_001", + "cmems_mod_ibi_phy_anfc_0.027deg-3D_P1M-m": "IBI_ANALYSISFORECAST_PHY_005_001", + "cmems_mod_ibi_phy_anfc_0.027deg-3D_PT1H-m": "IBI_ANALYSISFORECAST_PHY_005_001", + "cmems_mod_ibi_phy_anfc_0.027deg-3D_static": "IBI_ANALYSISFORECAST_PHY_005_001", + "cmems_mod_ibi_wav_anfc_0.05deg_PT1H-i": "IBI_ANALYSISFORECAST_WAV_005_005", + "cmems_mod_ibi_wav_anfc_0.05deg_static": "IBI_ANALYSISFORECAST_WAV_005_005", + "cmems_mod_ibi_bgc_my_0.083deg-3D-climatology_P1M-m": "IBI_MULTIYEAR_BGC_005_003", + "cmems_mod_ibi_bgc_my_0.083deg-3D_P1D-m": "IBI_MULTIYEAR_BGC_005_003", + "cmems_mod_ibi_bgc_my_0.083deg-3D_P1M-m": "IBI_MULTIYEAR_BGC_005_003", + "cmems_mod_ibi_bgc_my_0.083deg-3D_P1Y-m": "IBI_MULTIYEAR_BGC_005_003", + "cmems_mod_ibi_bgc_my_0.083deg-3D_static": "IBI_MULTIYEAR_BGC_005_003", + "cmems_mod_ibi_phy_my_0.083deg-2D_PT1H-m": "IBI_MULTIYEAR_PHY_005_002", + "cmems_mod_ibi_phy_my_0.083deg-3D-climatology_P1M-m": "IBI_MULTIYEAR_PHY_005_002", + "cmems_mod_ibi_phy_my_0.083deg-3D_P1D-m": "IBI_MULTIYEAR_PHY_005_002", + "cmems_mod_ibi_phy_my_0.083deg-3D_P1M-m": "IBI_MULTIYEAR_PHY_005_002", + "cmems_mod_ibi_phy_my_0.083deg-3D_P1Y-m": "IBI_MULTIYEAR_PHY_005_002", + "cmems_mod_ibi_phy_my_0.083deg-3D_static": "IBI_MULTIYEAR_PHY_005_002", + "cmems_mod_ibi_wav_my_0.027deg-climatology_P1M-m": "IBI_MULTIYEAR_WAV_005_006", + "cmems_mod_ibi_wav_my_0.027deg_PT1H-i": "IBI_MULTIYEAR_WAV_005_006", + "cmems_mod_ibi_wav_my_0.027deg_static": "IBI_MULTIYEAR_WAV_005_006", + "ibi_omi_currents_cui_index": "IBI_OMI_CURRENTS_cui", + "ibi_omi_currents_cui_trend": "IBI_OMI_CURRENTS_cui", + "ibi_omi_seastate_extreme_var_swh_mean_and_anomaly": "IBI_OMI_SEASTATE_extreme_var_swh_mean_and_anomaly", + "ibi_omi_seastate_swi_anomaly": "IBI_OMI_SEASTATE_swi", + "ibi_omi_seastate_swi_mean_percentile": "IBI_OMI_SEASTATE_swi", + "ibi_omi_tempsal_extreme_var_temp_mean_and_anomaly": "IBI_OMI_TEMPSAL_extreme_var_temp_mean_and_anomaly", + "ibi_omi_wmhe_mow_anomalies_north": "IBI_OMI_WMHE_mow", + "ibi_omi_wmhe_mow_anomalies_reservoir": "IBI_OMI_WMHE_mow", + "ibi_omi_wmhe_mow_anomalies_south": "IBI_OMI_WMHE_mow", + "ibi_omi_wmhe_mow_anomalies_west": "IBI_OMI_WMHE_mow", + "cmems_obs-ins_arc_phybgcwav_mynrt_na_irr": "INSITU_ARC_PHYBGCWAV_DISCRETE_MYNRT_013_031", + "cmems_obs-ins_bal_phybgcwav_mynrt_na_irr": "INSITU_BAL_PHYBGCWAV_DISCRETE_MYNRT_013_032", + "cmems_obs-ins_blk_phybgcwav_mynrt_na_irr": "INSITU_BLK_PHYBGCWAV_DISCRETE_MYNRT_013_034", + "cmems_obs-ins_glo_bgc-car_my_glodap-gridded_irr": "INSITU_GLO_BGC_CARBON_DISCRETE_MY_013_050", + "cmems_obs-ins_glo_bgc-car_my_glodap-obs_irr": "INSITU_GLO_BGC_CARBON_DISCRETE_MY_013_050", + "cmems_obs-ins_glo_bgc-car_my_socat-gridded_irr": "INSITU_GLO_BGC_CARBON_DISCRETE_MY_013_050", + "cmems_obs-ins_glo_bgc-car_my_socat-obs_irr": "INSITU_GLO_BGC_CARBON_DISCRETE_MY_013_050", + "cmems_obs-ins_glo_bgc-chl_my_na_irr": "INSITU_GLO_BGC_DISCRETE_MY_013_046", + "cmems_obs-ins_glo_bgc-nut_my_na_irr": "INSITU_GLO_BGC_DISCRETE_MY_013_046", + "cmems_obs-ins_glo_bgc-ox_my_na_irr": "INSITU_GLO_BGC_DISCRETE_MY_013_046", + "cmems_obs-ins_glo_phybgcwav_mynrt_na_irr": "INSITU_GLO_PHYBGCWAV_DISCRETE_MYNRT_013_030", + "cmems_obs-ins_glo_phy-ssh_my_na_PT1H": "INSITU_GLO_PHY_SSH_DISCRETE_MY_013_053", + "cmems_obs-ins_glo_phy-ssh_my_na_irr": "INSITU_GLO_PHY_SSH_DISCRETE_MY_013_053", + "cmems_obs-ins_ibi_phy-ssh_my_tide-surge_PT1H": "INSITU_GLO_PHY_SSH_DISCRETE_MY_013_053", + "cmems_obs-ins_glo_phy-temp-sal_my_cora_irr": "INSITU_GLO_PHY_TS_DISCRETE_MY_013_001", + "cmems_obs-ins_glo_phy-temp-sal_my_easycora_irr": "INSITU_GLO_PHY_TS_DISCRETE_MY_013_001", + "cmems_obs-ins_glo_phy-temp-sal_my_cora-oa_P1M": "INSITU_GLO_PHY_TS_OA_MY_013_052", + "cmems_obs-ins_glo_phy-temp-sal_nrt_oa_P1M": "INSITU_GLO_PHY_TS_OA_NRT_013_002", + "cmems_obs-ins_glo_phy-cur_my_adcp_irr": "INSITU_GLO_PHY_UV_DISCRETE_MY_013_044", + "cmems_obs-ins_glo_phy-cur_my_argo_irr": "INSITU_GLO_PHY_UV_DISCRETE_MY_013_044", + "cmems_obs-ins_glo_phy-cur_my_drifter_PT6H": "INSITU_GLO_PHY_UV_DISCRETE_MY_013_044", + "cmems_obs-ins_glo_phy-cur_my_radar-radial_irr": "INSITU_GLO_PHY_UV_DISCRETE_MY_013_044", + "cmems_obs-ins_glo_phy-cur_my_radar-total_irr": "INSITU_GLO_PHY_UV_DISCRETE_MY_013_044", + "cmems_obs-ins_glo_phy-cur_nrt_argo_irr": "INSITU_GLO_PHY_UV_DISCRETE_NRT_013_048", + "cmems_obs-ins_glo_phy-cur_nrt_drifter_irr": "INSITU_GLO_PHY_UV_DISCRETE_NRT_013_048", + "cmems_obs-ins_glo_phy-cur_nrt_radar-radial_irr": "INSITU_GLO_PHY_UV_DISCRETE_NRT_013_048", + "cmems_obs-ins_glo_phy-cur_nrt_radar-total_irr": "INSITU_GLO_PHY_UV_DISCRETE_NRT_013_048", + "cmems_obs-ins_glo_wav_my_na_PT1H": "INSITU_GLO_WAV_DISCRETE_MY_013_045", + "cmems_obs-ins_glo_wav_my_na_irr": "INSITU_GLO_WAV_DISCRETE_MY_013_045", + "cmems_obs-ins_ibi_phybgcwav_mynrt_na_irr": "INSITU_IBI_PHYBGCWAV_DISCRETE_MYNRT_013_033", + "cmems_obs-ins_med_phybgcwav_mynrt_na_irr": "INSITU_MED_PHYBGCWAV_DISCRETE_MYNRT_013_035", + "cmems_obs-ins_nws_phybgcwav_mynrt_na_irr": "INSITU_NWS_PHYBGCWAV_DISCRETE_MYNRT_013_036", + "cmems_mod_med_bgc-bio_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-bio_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-car_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-car_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-co2_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-co2_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-nut_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-nut_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-optics_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-optics_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-pft_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc-pft_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_bgc_anfc_4.2km_static": "MEDSEA_ANALYSISFORECAST_BGC_006_014", + "cmems_mod_med_phy-cur_anfc_4.2km-2D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-cur_anfc_4.2km-3D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-cur_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-cur_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-cur_anfc_4.2km_PT15M-i": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-cur_anfc_detided_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-mld_anfc_4.2km-2D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-mld_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-mld_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-sal_anfc_4.2km-2D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-sal_anfc_4.2km-3D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-sal_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-sal_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-ssh_anfc_4.2km-2D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-ssh_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-ssh_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-ssh_anfc_4.2km_PT15M-i": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-ssh_anfc_detided_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-tem_anfc_4.2km-2D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-tem_anfc_4.2km-3D_PT1H-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-tem_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-tem_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-wcur_anfc_4.2km_P1D-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy-wcur_anfc_4.2km_P1M-m": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_phy_anfc_4.2km_static": "MEDSEA_ANALYSISFORECAST_PHY_006_013", + "cmems_mod_med_wav_anfc_4.2km_PT1H-i": "MEDSEA_ANALYSISFORECAST_WAV_006_017", + "cmems_mod_med_wav_anfc_4.2km_static": "MEDSEA_ANALYSISFORECAST_WAV_006_017", + "cmems_mod_med_bgc-bio_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-bio_myint_4.2km_P1M-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-car_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-car_myint_4.2km_P1M-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-co2_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-co2_myint_4.2km_P1M-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-nut_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-nut_myint_4.2km_P1M-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-pft_myint_4.2km_P1M-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc-plankton_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc_my_4.2km-climatology_P1M-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_bgc_my_4.2km_static": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-bio-rean-d": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-bio-rean-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-car-rean-d": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-car-rean-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-co2-rean-d": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-co2-rean-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-nut-rean-d": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-nut-rean-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-pft-rean-d": "MEDSEA_MULTIYEAR_BGC_006_008", + "med-ogs-pft-rean-m": "MEDSEA_MULTIYEAR_BGC_006_008", + "cmems_mod_med_phy-cur_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_phy-mld_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_phy-sal_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_phy-ssh_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_phy-tem_my_4.2km_P1Y-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_phy_my_4.2km-climatology_P1M-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_phy_my_4.2km_static": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-cur-int-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-cur-rean-d": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-cur-rean-h": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-cur-rean-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-mld-int-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-mld-rean-d": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-mld-rean-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-sal-int-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-sal-rean-d": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-sal-rean-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-ssh-int-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-ssh-rean-d": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-ssh-rean-h": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-ssh-rean-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-tem-int-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-tem-rean-d": "MEDSEA_MULTIYEAR_PHY_006_004", + "med-cmcc-tem-rean-m": "MEDSEA_MULTIYEAR_PHY_006_004", + "cmems_mod_med_wav_my_4.2km-climatology_P1M-m": "MEDSEA_MULTIYEAR_WAV_006_012", + "cmems_mod_med_wav_my_4.2km_static": "MEDSEA_MULTIYEAR_WAV_006_012", + "cmems_mod_med_wav_myint_4.2km_PT1H-i": "MEDSEA_MULTIYEAR_WAV_006_012", + "med-hcmr-wav-rean-h": "MEDSEA_MULTIYEAR_WAV_006_012", + "medsea_omi_ohc_area_averaged_anomalies": "MEDSEA_OMI_OHC_area_averaged_anomalies", + "medsea_omi_seastate_extreme_var_swh_mean_and_anomaly": "MEDSEA_OMI_SEASTATE_extreme_var_swh_mean_and_anomaly", + "medsea_omi_tempsal_extreme_var_temp_mean_and_anomaly": "MEDSEA_OMI_TEMPSAL_extreme_var_temp_mean_and_anomaly", + "medsea_omi_tempsal_sst_area_averaged_anomalies": "MEDSEA_OMI_TEMPSAL_sst_area_averaged_anomalies", + "medsea_omi_tempsal_sst_trend": "MEDSEA_OMI_TEMPSAL_sst_trend", + "cmems_obs-mob_glo_bgc-nut-car_mynrt_irr_i": "MULTIOBS_GLO_BGC_NUTRIENTS_CARBON_PROFILES_MYNRT_015_009", + "cmems_obs_glo_bgc3d_rep_clim": "MULTIOBS_GLO_BIO_BGC_3D_REP_015_010", + "cmems_obs_glo_bgc3d_rep_weekly": "MULTIOBS_GLO_BIO_BGC_3D_REP_015_010", + "dataset-carbon-rep-monthly": "MULTIOBS_GLO_BIO_CARBON_SURFACE_REP_015_008", + "cmems_obs_mob_glo_phy-cur_my_0.25deg_P1D-m": "MULTIOBS_GLO_PHY_MYNRT_015_003", + "cmems_obs_mob_glo_phy-cur_my_0.25deg_P1M-m": "MULTIOBS_GLO_PHY_MYNRT_015_003", + "cmems_obs_mob_glo_phy-cur_my_0.25deg_PT1H-i": "MULTIOBS_GLO_PHY_MYNRT_015_003", + "cmems_obs_mob_glo_phy-cur_nrt_0.25deg_P1D-m": "MULTIOBS_GLO_PHY_MYNRT_015_003", + "cmems_obs_mob_glo_phy-cur_nrt_0.25deg_P1M-m": "MULTIOBS_GLO_PHY_MYNRT_015_003", + "cmems_obs_mob_glo_phy-cur_nrt_0.25deg_PT1H-i": "MULTIOBS_GLO_PHY_MYNRT_015_003", + "cmems_obs-mob_glo_phy-sss_mynrt_smos_P1D": "MULTIOBS_GLO_PHY_SSS_L3_MYNRT_015_014", + "cmems_obs-mob_glo_phy-sss_my_multi-oi_P1W": "MULTIOBS_GLO_PHY_SSS_L4_MY_015_015", + "cmems_obs-mob_glo_phy-sss_my_multi_P1D": "MULTIOBS_GLO_PHY_S_SURFACE_MYNRT_015_013", + "cmems_obs-mob_glo_phy-sss_my_multi_P1M": "MULTIOBS_GLO_PHY_S_SURFACE_MYNRT_015_013", + "cmems_obs-mob_glo_phy-sss_nrt_multi_P1D": "MULTIOBS_GLO_PHY_S_SURFACE_MYNRT_015_013", + "cmems_obs-mob_glo_phy-sss_nrt_multi_P1M": "MULTIOBS_GLO_PHY_S_SURFACE_MYNRT_015_013", + "dataset-armor-3d-nrt-monthly": "MULTIOBS_GLO_PHY_TSUV_3D_MYNRT_015_012", + "dataset-armor-3d-nrt-weekly": "MULTIOBS_GLO_PHY_TSUV_3D_MYNRT_015_012", + "dataset-armor-3d-rep-monthly": "MULTIOBS_GLO_PHY_TSUV_3D_MYNRT_015_012", + "dataset-armor-3d-rep-weekly": "MULTIOBS_GLO_PHY_TSUV_3D_MYNRT_015_012", + "dataset-omega-3d-rep-weekly": "MULTIOBS_GLO_PHY_W_3D_REP_015_007", + "northwestshelf_omi_tempsal_extreme_var_temp_mean_and_anomaly": "NORTHWESTSHELF_OMI_TEMPSAL_extreme_var_temp_mean_and_anomaly", + "cmems_mod_nws_bgc_anfc_0.027deg-3D_P1D-m": "NWSHELF_ANALYSISFORECAST_BGC_004_002", + "cmems_mod_nws_bgc_anfc_0.027deg-3D_P1M-m": "NWSHELF_ANALYSISFORECAST_BGC_004_002", + "cmems_mod_nws_bgc_anfc_0.027deg-3D_static": "NWSHELF_ANALYSISFORECAST_BGC_004_002", + "cmems_mod_nws_phy_anfc_0.027deg-2D_PT15M-i": "NWSHELF_ANALYSISFORECAST_PHY_004_013", + "cmems_mod_nws_phy_anfc_0.027deg-2D_PT1H-m": "NWSHELF_ANALYSISFORECAST_PHY_004_013", + "cmems_mod_nws_phy_anfc_0.027deg-3D_P1D-m": "NWSHELF_ANALYSISFORECAST_PHY_004_013", + "cmems_mod_nws_phy_anfc_0.027deg-3D_P1M-m": "NWSHELF_ANALYSISFORECAST_PHY_004_013", + "cmems_mod_nws_phy_anfc_0.027deg-3D_PT1H-m": "NWSHELF_ANALYSISFORECAST_PHY_004_013", + "cmems_mod_nws_phy_anfc_0.027deg-3D_static": "NWSHELF_ANALYSISFORECAST_PHY_004_013", + "cmems_mod_nws_wav_anfc_0.05deg_PT1H-i": "NWSHELF_ANALYSISFORECAST_WAV_004_014", + "cmems_mod_nws_wav_anfc_0.05deg_static": "NWSHELF_ANALYSISFORECAST_WAV_004_014", + "cmems_mod_nws_bgc-chl_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-chl_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-chl_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-kd_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-kd_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-kd_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-no3_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-no3_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-no3_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-o2_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-o2_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-o2_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-diato_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-diato_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-dino_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-dino_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-nano_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-nano_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-pico_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_my_7km-3D-pico_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_myint_7km-3D-diato_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_myint_7km-3D-dino_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_myint_7km-3D-nano_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pft_myint_7km-3D-pico_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-ph_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-ph_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-ph_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-phyc_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-phyc_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-phyc_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-po4_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-po4_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-po4_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pp_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pp_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-pp_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-spco2_my_7km-2D_P1D-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-spco2_my_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_bgc-spco2_myint_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_BGC_004_011", + "cmems_mod_nws_phy-bottomt_my_7km-2D_P1D-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-bottomt_my_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-bottomt_my_7km-2D_PT1H-i": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-bottomt_myint_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-mld_my_7km-2D_P1D-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-mld_my_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-mld_my_7km-2D_PT1H-i": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-mld_myint_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-s_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-s_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-s_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-ssh_my_7km-2D_P1D-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-ssh_my_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-ssh_my_7km-2D_PT1H-i": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-ssh_myint_7km-2D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-sss_my_7km-2D_PT1H-i": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-sst_my_7km-2D_PT1H-i": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-t_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-t_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-t_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-uv_my_7km-2D_PT1H-i": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-uv_my_7km-3D_P1D-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-uv_my_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "cmems_mod_nws_phy-uv_myint_7km-3D_P1M-m": "NWSHELF_MULTIYEAR_PHY_004_009", + "MetO-NWS-WAV-RAN": "NWSHELF_REANALYSIS_WAV_004_015", + "cmems_obs_oc_arc_bgc_geophy_nrt_l3-hr_P1D-m": "OCEANCOLOUR_ARC_BGC_HR_L3_NRT_009_201", + "cmems_obs_oc_arc_bgc_optics_nrt_l3-hr_P1D-m": "OCEANCOLOUR_ARC_BGC_HR_L3_NRT_009_201", + "cmems_obs_oc_arc_bgc_transp_nrt_l3-hr_P1D-m": "OCEANCOLOUR_ARC_BGC_HR_L3_NRT_009_201", + "cmems_obs_oc_arc_bgc_geophy_nrt_l4-hr_P1D-m": "OCEANCOLOUR_ARC_BGC_HR_L4_NRT_009_207", + "cmems_obs_oc_arc_bgc_geophy_nrt_l4-hr_P1M-m": "OCEANCOLOUR_ARC_BGC_HR_L4_NRT_009_207", + "cmems_obs_oc_arc_bgc_optics_nrt_l4-hr_P1D-m": "OCEANCOLOUR_ARC_BGC_HR_L4_NRT_009_207", + "cmems_obs_oc_arc_bgc_optics_nrt_l4-hr_P1M-m": "OCEANCOLOUR_ARC_BGC_HR_L4_NRT_009_207", + "cmems_obs_oc_arc_bgc_transp_nrt_l4-hr_P1D-m": "OCEANCOLOUR_ARC_BGC_HR_L4_NRT_009_207", + "cmems_obs_oc_arc_bgc_transp_nrt_l4-hr_P1M-m": "OCEANCOLOUR_ARC_BGC_HR_L4_NRT_009_207", + "cmems_obs-oc_arc_bgc-plankton_my_l3-multi-4km_P1D": "OCEANCOLOUR_ARC_BGC_L3_MY_009_123", + "cmems_obs-oc_arc_bgc-plankton_my_l3-olci-300m_P1D": "OCEANCOLOUR_ARC_BGC_L3_MY_009_123", + "cmems_obs-oc_arc_bgc-reflectance_my_l3-multi-4km_P1D": "OCEANCOLOUR_ARC_BGC_L3_MY_009_123", + "cmems_obs-oc_arc_bgc-reflectance_my_l3-olci-300m_P1D": "OCEANCOLOUR_ARC_BGC_L3_MY_009_123", + "cmems_obs-oc_arc_bgc-transp_my_l3-multi-4km_P1D": "OCEANCOLOUR_ARC_BGC_L3_MY_009_123", + "cmems_obs-oc_arc_bgc-transp_my_l3-olci-300m_P1D": "OCEANCOLOUR_ARC_BGC_L3_MY_009_123", + "cmems_obs-oc_arc_bgc-plankton_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_ARC_BGC_L3_NRT_009_121", + "cmems_obs-oc_arc_bgc-reflectance_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_ARC_BGC_L3_NRT_009_121", + "cmems_obs-oc_arc_bgc-transp_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_ARC_BGC_L3_NRT_009_121", + "cmems_obs-oc_arc_bgc-plankton_my_l4-multi-4km_P1M": "OCEANCOLOUR_ARC_BGC_L4_MY_009_124", + "cmems_obs-oc_arc_bgc-plankton_my_l4-multi-climatology-4km_P1D": "OCEANCOLOUR_ARC_BGC_L4_MY_009_124", + "cmems_obs-oc_arc_bgc-plankton_my_l4-olci-300m_P1M": "OCEANCOLOUR_ARC_BGC_L4_MY_009_124", + "cmems_obs-oc_arc_bgc-plankton_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_ARC_BGC_L4_NRT_009_122", + "cmems_obs-oc_arc_bgc-transp_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_ARC_BGC_L4_NRT_009_122", + "cmems_obs-oc_atl_bgc-optics_my_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_MY_009_113", + "cmems_obs-oc_atl_bgc-plankton_my_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_MY_009_113", + "cmems_obs-oc_atl_bgc-plankton_my_l3-olci-300m_P1D": "OCEANCOLOUR_ATL_BGC_L3_MY_009_113", + "cmems_obs-oc_atl_bgc-reflectance_my_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_MY_009_113", + "cmems_obs-oc_atl_bgc-reflectance_my_l3-olci-300m_P1D": "OCEANCOLOUR_ATL_BGC_L3_MY_009_113", + "cmems_obs-oc_atl_bgc-transp_my_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_MY_009_113", + "cmems_obs-oc_atl_bgc-optics_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_NRT_009_111", + "cmems_obs-oc_atl_bgc-plankton_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_NRT_009_111", + "cmems_obs-oc_atl_bgc-plankton_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_ATL_BGC_L3_NRT_009_111", + "cmems_obs-oc_atl_bgc-reflectance_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_NRT_009_111", + "cmems_obs-oc_atl_bgc-reflectance_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_ATL_BGC_L3_NRT_009_111", + "cmems_obs-oc_atl_bgc-transp_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L3_NRT_009_111", + "cmems_obs-oc_atl_bgc-plankton_my_l4-gapfree-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L4_MY_009_118", + "cmems_obs-oc_atl_bgc-plankton_my_l4-multi-1km_P1M": "OCEANCOLOUR_ATL_BGC_L4_MY_009_118", + "cmems_obs-oc_atl_bgc-pp_my_l4-multi-1km_P1M": "OCEANCOLOUR_ATL_BGC_L4_MY_009_118", + "cmems_obs-oc_atl_bgc-plankton_nrt_l4-gapfree-multi-1km_P1D": "OCEANCOLOUR_ATL_BGC_L4_NRT_009_116", + "cmems_obs-oc_atl_bgc-plankton_nrt_l4-multi-1km_P1M": "OCEANCOLOUR_ATL_BGC_L4_NRT_009_116", + "cmems_obs-oc_atl_bgc-pp_nrt_l4-multi-1km_P1M": "OCEANCOLOUR_ATL_BGC_L4_NRT_009_116", + "cmems_obs_oc_bal_bgc_geophy_nrt_l3-hr_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L3_NRT_009_202", + "cmems_obs_oc_bal_bgc_optics_nrt_l3-hr_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L3_NRT_009_202", + "cmems_obs_oc_bal_bgc_transp_nrt_l3-hr_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L3_NRT_009_202", + "cmems_obs_oc_bal_bgc_tur-spm-chl_nrt_l3-hr-mosaic_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L3_NRT_009_202", + "cmems_obs_oc_bal_bgc_geophy_nrt_l4-hr_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs_oc_bal_bgc_geophy_nrt_l4-hr_P1M-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs_oc_bal_bgc_optics_nrt_l4-hr_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs_oc_bal_bgc_optics_nrt_l4-hr_P1M-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs_oc_bal_bgc_transp_nrt_l4-hr_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs_oc_bal_bgc_transp_nrt_l4-hr_P1M-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs_oc_bal_bgc_tur-spm-chl_nrt_l4-hr-mosaic_P1D-m": "OCEANCOLOUR_BAL_BGC_HR_L4_NRT_009_208", + "cmems_obs-oc_bal_bgc-optics_my_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-plankton_my_l3-multi-1km_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-plankton_my_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-reflectance_my_l3-multi-1km_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-reflectance_my_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-transp_my_l3-multi-1km_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-transp_my_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_MY_009_133", + "cmems_obs-oc_bal_bgc-optics_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_NRT_009_131", + "cmems_obs-oc_bal_bgc-plankton_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_NRT_009_131", + "cmems_obs-oc_bal_bgc-reflectance_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_NRT_009_131", + "cmems_obs-oc_bal_bgc-transp_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BAL_BGC_L3_NRT_009_131", + "cmems_obs-oc_bal_bgc-plankton_my_l4-multi-1km_P1M": "OCEANCOLOUR_BAL_BGC_L4_MY_009_134", + "cmems_obs-oc_bal_bgc-plankton_my_l4-olci-300m_P1M": "OCEANCOLOUR_BAL_BGC_L4_MY_009_134", + "cmems_obs-oc_bal_bgc-plankton_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_BAL_BGC_L4_NRT_009_132", + "cmems_obs_oc_blk_bgc_geophy_nrt_l3-hr_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L3_NRT_009_206", + "cmems_obs_oc_blk_bgc_optics_nrt_l3-hr_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L3_NRT_009_206", + "cmems_obs_oc_blk_bgc_transp_nrt_l3-hr_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L3_NRT_009_206", + "cmems_obs_oc_blk_bgc_tur-spm-chl_nrt_l3-hr-mosaic_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L3_NRT_009_206", + "cmems_obs_oc_blk_bgc_geophy_nrt_l4-hr_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs_oc_blk_bgc_geophy_nrt_l4-hr_P1M-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs_oc_blk_bgc_optics_nrt_l4-hr_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs_oc_blk_bgc_optics_nrt_l4-hr_P1M-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs_oc_blk_bgc_transp_nrt_l4-hr_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs_oc_blk_bgc_transp_nrt_l4-hr_P1M-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs_oc_blk_bgc_tur-spm-chl_nrt_l4-hr-mosaic_P1D-m": "OCEANCOLOUR_BLK_BGC_HR_L4_NRT_009_212", + "cmems_obs-oc_blk_bgc-optics_my_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-plankton_my_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-plankton_my_l3-olci-300m_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-reflectance_my_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-reflectance_my_l3-olci-300m_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-transp_my_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-transp_my_l3-olci-300m_P1D": "OCEANCOLOUR_BLK_BGC_L3_MY_009_153", + "cmems_obs-oc_blk_bgc-optics_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-plankton_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-plankton_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-reflectance_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-reflectance_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-transp_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-transp_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_BLK_BGC_L3_NRT_009_151", + "cmems_obs-oc_blk_bgc-plankton_my_l4-gapfree-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L4_MY_009_154", + "cmems_obs-oc_blk_bgc-plankton_my_l4-multi-1km_P1M": "OCEANCOLOUR_BLK_BGC_L4_MY_009_154", + "cmems_obs-oc_blk_bgc-plankton_my_l4-multi-climatology-1km_P1D": "OCEANCOLOUR_BLK_BGC_L4_MY_009_154", + "cmems_obs-oc_blk_bgc-plankton_my_l4-olci-300m_P1M": "OCEANCOLOUR_BLK_BGC_L4_MY_009_154", + "cmems_obs-oc_blk_bgc-plankton_nrt_l4-gapfree-multi-1km_P1D": "OCEANCOLOUR_BLK_BGC_L4_NRT_009_152", + "cmems_obs-oc_blk_bgc-plankton_nrt_l4-multi-1km_P1M": "OCEANCOLOUR_BLK_BGC_L4_NRT_009_152", + "cmems_obs-oc_blk_bgc-plankton_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_BLK_BGC_L4_NRT_009_152", + "cmems_obs-oc_blk_bgc-transp_nrt_l4-multi-1km_P1M": "OCEANCOLOUR_BLK_BGC_L4_NRT_009_152", + "cmems_obs-oc_blk_bgc-transp_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_BLK_BGC_L4_NRT_009_152", + "cmems_obs-oc_glo_bgc-optics_my_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-plankton_my_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-plankton_my_l3-olci-300m_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-plankton_my_l3-olci-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-reflectance_my_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-reflectance_my_l3-olci-300m_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-reflectance_my_l3-olci-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-transp_my_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "cmems_obs-oc_glo_bgc-transp_my_l3-olci-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_103", + "c3s_obs-oc_glo_bgc-plankton_my_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_107", + "c3s_obs-oc_glo_bgc-reflectance_my_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_MY_009_107", + "cmems_obs-oc_glo_bgc-optics_nrt_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-plankton_nrt_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-plankton_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-plankton_nrt_l3-olci-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-reflectance_nrt_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-reflectance_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-reflectance_nrt_l3-olci-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-transp_nrt_l3-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-transp_nrt_l3-olci-4km_P1D": "OCEANCOLOUR_GLO_BGC_L3_NRT_009_101", + "cmems_obs-oc_glo_bgc-optics_my_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-plankton_my_l4-gapfree-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-plankton_my_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-plankton_my_l4-multi-climatology-4km_P1D": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-plankton_my_l4-olci-300m_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-plankton_my_l4-olci-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-pp_my_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-reflectance_my_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-reflectance_my_l4-olci-300m_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-reflectance_my_l4-olci-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-transp_my_l4-gapfree-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-transp_my_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "cmems_obs-oc_glo_bgc-transp_my_l4-olci-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_104", + "c3s_obs-oc_glo_bgc-plankton_my_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_MY_009_108", + "cmems_obs-oc_glo_bgc-optics_nrt_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-plankton_nrt_l4-gapfree-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-plankton_nrt_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-plankton_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-plankton_nrt_l4-olci-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-pp_nrt_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-reflectance_nrt_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-reflectance_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-reflectance_nrt_l4-olci-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-transp_nrt_l4-gapfree-multi-4km_P1D": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-transp_nrt_l4-multi-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs-oc_glo_bgc-transp_nrt_l4-olci-4km_P1M": "OCEANCOLOUR_GLO_BGC_L4_NRT_009_102", + "cmems_obs_oc_ibi_bgc_geophy_nrt_l3-hr_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L3_NRT_009_204", + "cmems_obs_oc_ibi_bgc_optics_nrt_l3-hr_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L3_NRT_009_204", + "cmems_obs_oc_ibi_bgc_transp_nrt_l3-hr_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L3_NRT_009_204", + "cmems_obs_oc_ibi_bgc_tur-spm-chl_nrt_l3-hr-mosaic_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L3_NRT_009_204", + "cmems_obs_oc_ibi_bgc_geophy_nrt_l4-hr_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_ibi_bgc_geophy_nrt_l4-hr_P1M-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_ibi_bgc_optics_nrt_l4-hr_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_ibi_bgc_optics_nrt_l4-hr_P1M-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_ibi_bgc_transp_nrt_l4-hr_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_ibi_bgc_transp_nrt_l4-hr_P1M-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_ibi_bgc_tur-spm-chl_nrt_l4-hr-mosaic_P1D-m": "OCEANCOLOUR_IBI_BGC_HR_L4_NRT_009_210", + "cmems_obs_oc_med_bgc_geophy_nrt_l3-hr_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L3_NRT_009_205", + "cmems_obs_oc_med_bgc_optics_nrt_l3-hr_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L3_NRT_009_205", + "cmems_obs_oc_med_bgc_transp_nrt_l3-hr_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L3_NRT_009_205", + "cmems_obs_oc_med_bgc_tur-spm-chl_nrt_l3-hr-mosaic_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L3_NRT_009_205", + "cmems_obs_oc_med_bgc_geophy_nrt_l4-hr_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs_oc_med_bgc_geophy_nrt_l4-hr_P1M-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs_oc_med_bgc_optics_nrt_l4-hr_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs_oc_med_bgc_optics_nrt_l4-hr_P1M-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs_oc_med_bgc_transp_nrt_l4-hr_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs_oc_med_bgc_transp_nrt_l4-hr_P1M-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs_oc_med_bgc_tur-spm-chl_nrt_l4-hr-mosaic_P1D-m": "OCEANCOLOUR_MED_BGC_HR_L4_NRT_009_211", + "cmems_obs-oc_med_bgc-optics_my_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-plankton_my_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-plankton_my_l3-olci-300m_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-reflectance_my_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-reflectance_my_l3-olci-300m_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-transp_my_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-transp_my_l3-olci-300m_P1D": "OCEANCOLOUR_MED_BGC_L3_MY_009_143", + "cmems_obs-oc_med_bgc-optics_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-plankton_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-plankton_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-reflectance_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-reflectance_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-transp_nrt_l3-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-transp_nrt_l3-olci-300m_P1D": "OCEANCOLOUR_MED_BGC_L3_NRT_009_141", + "cmems_obs-oc_med_bgc-plankton_my_l4-gapfree-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L4_MY_009_144", + "cmems_obs-oc_med_bgc-plankton_my_l4-multi-1km_P1M": "OCEANCOLOUR_MED_BGC_L4_MY_009_144", + "cmems_obs-oc_med_bgc-plankton_my_l4-multi-climatology-1km_P1D": "OCEANCOLOUR_MED_BGC_L4_MY_009_144", + "cmems_obs-oc_med_bgc-plankton_my_l4-olci-300m_P1M": "OCEANCOLOUR_MED_BGC_L4_MY_009_144", + "cmems_obs-oc_med_bgc-pp_my_l4-multi-4km_P1D": "OCEANCOLOUR_MED_BGC_L4_MY_009_144", + "cmems_obs-oc_med_bgc-pp_my_l4-multi-4km_P1M": "OCEANCOLOUR_MED_BGC_L4_MY_009_144", + "cmems_obs-oc_med_bgc-plankton_nrt_l4-gapfree-multi-1km_P1D": "OCEANCOLOUR_MED_BGC_L4_NRT_009_142", + "cmems_obs-oc_med_bgc-plankton_nrt_l4-multi-1km_P1M": "OCEANCOLOUR_MED_BGC_L4_NRT_009_142", + "cmems_obs-oc_med_bgc-plankton_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_MED_BGC_L4_NRT_009_142", + "cmems_obs-oc_med_bgc-transp_nrt_l4-multi-1km_P1M": "OCEANCOLOUR_MED_BGC_L4_NRT_009_142", + "cmems_obs-oc_med_bgc-transp_nrt_l4-olci-300m_P1M": "OCEANCOLOUR_MED_BGC_L4_NRT_009_142", + "cmems_obs_oc_nws_bgc_geophy_nrt_l3-hr_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L3_NRT_009_203", + "cmems_obs_oc_nws_bgc_optics_nrt_l3-hr_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L3_NRT_009_203", + "cmems_obs_oc_nws_bgc_transp_nrt_l3-hr_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L3_NRT_009_203", + "cmems_obs_oc_nws_bgc_tur-spm-chl_nrt_l3-hr-mosaic_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L3_NRT_009_203", + "cmems_obs_oc_nws_bgc_geophy_nrt_l4-hr_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "cmems_obs_oc_nws_bgc_geophy_nrt_l4-hr_P1M-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "cmems_obs_oc_nws_bgc_optics_nrt_l4-hr_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "cmems_obs_oc_nws_bgc_optics_nrt_l4-hr_P1M-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "cmems_obs_oc_nws_bgc_transp_nrt_l4-hr_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "cmems_obs_oc_nws_bgc_transp_nrt_l4-hr_P1M-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "cmems_obs_oc_nws_bgc_tur-spm-chl_nrt_l4-hr-mosaic_P1D-m": "OCEANCOLOUR_NWS_BGC_HR_L4_NRT_009_209", + "blksea_omi_circulation_rim_current_index": "OMI_CIRCULATION_BOUNDARY_BLKSEA_rim_current_index", + "omi_circulation_boundary_pacific_kuroshio_phase_area_averaged": "OMI_CIRCULATION_BOUNDARY_PACIFIC_kuroshio_phase_area_averaged", + "omi_circulation_moc_medsea_area_averaged_mean": "OMI_CIRCULATION_MOC_MEDSEA_area_averaged_mean", + "omi_circulation_voltrans_arctic_averaged": "OMI_CIRCULATION_VOLTRANS_ARCTIC_averaged", + "omi_climate_ohc_blksea_area_averaged_anomalies": "OMI_CLIMATE_OHC_BLKSEA_area_averaged_anomalies", + "omi_climate_ohc_ibi_area_averaged_anomalies": "OMI_CLIMATE_OHC_IBI_area_averaged_anomalies", + "omi_climate_osc_medsea_volume_mean": "OMI_CLIMATE_OSC_MEDSEA_volume_mean", + "omi_climate_sl_baltic_area_averaged_anomalies": "OMI_CLIMATE_SL_BALTIC_area_averaged_anomalies", + "omi_climate_sl_blksea_area_averaged_anomalies": "OMI_CLIMATE_SL_BLKSEA_area_averaged_anomalies", + "omi_climate_sl_europe_area_averaged_anomalies": "OMI_CLIMATE_SL_EUROPE_area_averaged_anomalies", + "omi_climate_sl_global_area_averaged_anomalies": "OMI_CLIMATE_SL_GLOBAL_area_averaged_anomalies", + "omi_climate_sl_global_regional_trends": "OMI_CLIMATE_SL_GLOBAL_regional_trends", + "omi_climate_sl_ibi_area_averaged_anomalies": "OMI_CLIMATE_SL_IBI_area_averaged_anomalies", + "omi_climate_sl_medsea_area_averaged_anomalies": "OMI_CLIMATE_SL_MEDSEA_area_averaged_anomalies", + "omi_climate_sl_northwestshelf_area_averaged_anomalies": "OMI_CLIMATE_SL_NORTHWESTSHELF_area_averaged_anomalies", + "omi_climate_sst_bal_area_averaged_anomalies": "OMI_CLIMATE_SST_BAL_area_averaged_anomalies", + "omi_climate_sst_bal_trend": "OMI_CLIMATE_SST_BAL_trend", + "omi_climate_sst_ibi_area_averaged_anomalies": "OMI_CLIMATE_SST_IBI_area_averaged_anomalies", + "omi_climate_sst_ibi_trend": "OMI_CLIMATE_SST_IBI_trend", + "omi_climate_sst_ist_arctic_area_averaged_anomalies": "OMI_CLIMATE_SST_IST_ARCTIC_area_averaged_anomalies", + "omi_climate_sst_ist_arctic_anomaly": "OMI_CLIMATE_SST_IST_ARCTIC_trend", + "omi_climate_sst_northwestshelf_area_averaged_anomalies": "OMI_CLIMATE_SST_NORTHWESTSHELF_area_averaged_anomalies", + "omi_climate_sst_northwestshelf_trend": "OMI_CLIMATE_SST_NORTHWESTSHELF_trend", + "omi_extreme_climvar_pacific_npgo_sla_eof_mode_projection": "OMI_EXTREME_CLIMVAR_PACIFIC_npgo_sla_eof_mode_projection", + "omi_extreme_sl_baltic_slev_mean_and_anomaly_obs": "OMI_EXTREME_SL_BALTIC_slev_mean_and_anomaly_obs", + "omi_extreme_sl_ibi_slev_mean_and_anomaly_obs": "OMI_EXTREME_SL_IBI_slev_mean_and_anomaly_obs", + "omi_extreme_sl_medsea_slev_mean_and_anomaly_obs": "OMI_EXTREME_SL_MEDSEA_slev_mean_and_anomaly_obs", + "omi_extreme_sl_northwestshelf_slev_mean_and_anomaly_obs": "OMI_EXTREME_SL_NORTHWESTSHELF_slev_mean_and_anomaly_obs", + "omi_extreme_sst_baltic_sst_mean_and_anomaly_obs": "OMI_EXTREME_SST_BALTIC_sst_mean_and_anomaly_obs", + "omi_extreme_sst_ibi_sst_mean_and_anomaly_obs": "OMI_EXTREME_SST_IBI_sst_mean_and_anomaly_obs", + "omi_extreme_sst_medsea_sst_mean_and_anomaly_obs": "OMI_EXTREME_SST_MEDSEA_sst_mean_and_anomaly_obs", + "omi_extreme_sst_northwestshelf_sst_mean_and_anomaly_obs": "OMI_EXTREME_SST_NORTHWESTSHELF_sst_mean_and_anomaly_obs", + "omi_extreme_wave_baltic_swh_mean_and_anomaly_obs": "OMI_EXTREME_WAVE_BALTIC_swh_mean_and_anomaly_obs", + "omi_extreme_wave_ibi_swh_mean_and_anomaly_obs": "OMI_EXTREME_WAVE_IBI_swh_mean_and_anomaly_obs", + "omi_extreme_wave_medsea_swh_mean_and_anomaly_obs": "OMI_EXTREME_WAVE_MEDSEA_swh_mean_and_anomaly_obs", + "omi_extreme_wave_northwestshelf_swh_mean_and_anomaly_obs": "OMI_EXTREME_WAVE_NORTHWESTSHELF_swh_mean_and_anomaly_obs", + "omi_health_chl_arctic_oceancolour_area_averaged_mean": "OMI_HEALTH_CHL_ARCTIC_OCEANCOLOUR_area_averaged_mean", + "omi_health_chl_atlantic_oceancolour_area_averaged_mean": "OMI_HEALTH_CHL_ATLANTIC_OCEANCOLOUR_area_averaged_mean", + "omi_health_chl_baltic_oceancolour_area_averaged_mean": "OMI_HEALTH_CHL_BALTIC_OCEANCOLOUR_area_averaged_mean", + "omi_health_chl_baltic_oceancolour_trend": "OMI_HEALTH_CHL_BALTIC_OCEANCOLOUR_trend", + "omi_health_chl_blksea_oceancolour_area_averaged_mean": "OMI_HEALTH_CHL_BLKSEA_OCEANCOLOUR_area_averaged_mean", + "omi_health_chl_blksea_oceancolour_trend": "OMI_HEALTH_CHL_BLKSEA_OCEANCOLOUR_trend", + "omi_health_chl_global_oceancolour_oligo_nag_area_mean": "OMI_HEALTH_CHL_GLOBAL_OCEANCOLOUR_oligo_nag_area_mean", + "omi_health_chl_global_oceancolour_oligo_npg_area_mean": "OMI_HEALTH_CHL_GLOBAL_OCEANCOLOUR_oligo_npg_area_mean", + "omi_health_chl_global_oceancolour_oligo_sag_area_mean": "OMI_HEALTH_CHL_GLOBAL_OCEANCOLOUR_oligo_sag_area_mean", + "omi_health_chl_global_oceancolour_oligo_spg_area_mean": "OMI_HEALTH_CHL_GLOBAL_OCEANCOLOUR_oligo_spg_area_mean", + "omi_health_chl_global_oceancolour_trend": "OMI_HEALTH_CHL_GLOBAL_OCEANCOLOUR_trend", + "omi_health_chl_medsea_oceancolour_area_averaged_mean": "OMI_HEALTH_CHL_MEDSEA_OCEANCOLOUR_area_averaged_mean", + "omi_health_chl_medsea_oceancolour_trend": "OMI_HEALTH_CHL_MEDSEA_OCEANCOLOUR_trend", + "omi_var_extreme_wmf_medsea_area_averaged_mean": "OMI_VAR_EXTREME_WMF_MEDSEA_area_averaged_mean", + "cmems_obs-si_ant_phy_nrt_l3-1km_P1D": "SEAICE_ANT_PHY_AUTO_L3_NRT_011_012", + "cmems_obs-si_ant_physic_my_drift-amsr_P2D": "SEAICE_ANT_PHY_L3_MY_011_018", + "cmems_obs-si_ant_physic_my_drift-amsr_P3D": "SEAICE_ANT_PHY_L3_MY_011_018", + "cmems_obs-si_arc_phy-icetype_nrt_L4-auto_P1D": "SEAICE_ARC_PHY_AUTO_L4_NRT_011_015", + "cmems_obs-si_arc_phy-siconc_nrt_L4-auto_P1D": "SEAICE_ARC_PHY_AUTO_L4_NRT_011_015", + "cmems_obs-si_arc_phy_nrt_l3_P1D": "SEAICE_ARC_PHY_AUTO_L4_NRT_011_015", + "cmems_obs-si_arc_phy_my_L3S-DMIOI_P1D-m": "SEAICE_ARC_PHY_CLIMATE_L3_MY_011_021", + "cmems_obs_si_arc_phy_my_L4-DMIOI_P1D-m": "SEAICE_ARC_PHY_CLIMATE_L4_MY_011_016", + "cmems_obs-si_arc_physic_nrt_L2-EW_PT1H-irr": "SEAICE_ARC_PHY_L3M_NRT_011_017", + "esa_obs-si_arc_phy-sit_nrt_l4_multi_P1D-m": "SEAICE_ARC_PHY_L4_NRT_011_014", + "CERSAT-GLO-SEAICE_30DAYS_DRIFT_ASCAT_SSMI_MERGED_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_30DAYS_DRIFT_QUICKSCAT_SSMI_MERGED_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_3DAYS_DRIFT_ASCAT_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_3DAYS_DRIFT_ASCAT_SSMI_MERGED_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_3DAYS_DRIFT_QUICKSCAT_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_3DAYS_DRIFT_QUICKSCAT_SSMI_MERGED_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_6DAYS_DRIFT_ASCAT_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "CERSAT-GLO-SEAICE_6DAYS_DRIFT_QUICKSCAT_RAN-OBS_FULL_TIME_SERIE": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "cmems_obs-si_arc_phy-drift_my_l3-ssmi_P30D": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "cmems_obs-si_arc_phy-drift_my_l3-ssmi_P3D": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "cmems_obs-si_arc_phy_my_drift-amsr_P2D": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "cmems_obs-si_arc_phy_my_drift-amsr_P3D": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "cmems_obs-si_arc_phy_my_drift-amsr_P6D": "SEAICE_ARC_SEAICE_L3_REP_OBSERVATIONS_011_010", + "METNO-ARC-SEAICE_CONC-L4-NRT-OBS": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_002", + "cmems_obs-si_arc_physic_nrt_1km-grl_P1D-irr": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_002", + "cmems_obs-si_arc_physic_nrt_1km-grl_P1WT3D-m": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_002", + "DMI-ARC-SEAICE_BERG-L4-NRT-OBS": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_007", + "DMI-ARC-SEAICE_BERG_IW-L4-NRT-OBS": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_007", + "DMI-ARC-SEAICE_BERG_MOSAIC-L4-NRT-OBS": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_007", + "DMI-ARC-SEAICE_BERG_MOSAIC_IW-L4-NRT-OBS": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_007", + "cmems_sat-si_arc_berg-point_nrt_ew_d": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_007", + "cmems_sat-si_arc_berg-point_nrt_iw_d": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_007", + "DMI-ARC-SEAICE_TEMP-L4-NRT-OBS": "SEAICE_ARC_SEAICE_L4_NRT_OBSERVATIONS_011_008", + "cmems_obs-si_bal_phy-sit_my_l4-1km_P1D-m": "SEAICE_BAL_PHY_L4_MY_011_019", + "cmems_obs-si_bal_seaice-conc_my_1km": "SEAICE_BAL_PHY_L4_MY_011_019", + "FMI-BAL-SEAICE_CONC-L4-NRT-OBS": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_004", + "FMI-BAL-SEAICE_THICK-L4-NRT-OBS": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_004", + "cmems_obs-si_bal_phy-sie_nrt_l4_P1D-m": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_004", + "FMI-BAL-SEAICE_DRIFT-SAR-NRT-OBS": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "FMI-BAL-SEAICE_THICK-MOSAIC-SAR-NRT-OBS": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "FMI-BAL-SEAICE_THICK-SAR-NRT-OBS": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "cmems_obs-si_bal_phy-sie_nrt_500m_P1D-m": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "cmems_obs-si_bal_phy-sit_nrt_x-500m-l4_P1D": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "cmems_sat-si_bal_conc_nrt_500m_d": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "cmems_sat-si_bal_thick_nrt_500m_hi": "SEAICE_BAL_SEAICE_L4_NRT_OBSERVATIONS_011_011", + "c3s_obs-si_glo_phy_my_nh-l3_P1M": "SEAICE_GLO_PHY_CLIMATE_L3_MY_011_013", + "cmems_obs-si_glo_phy-drift-north_my_l4_P1D-m": "SEAICE_GLO_PHY_L4_MY_011_020", + "cmems_obs-si_glo_phy-drift-south_my_l4_P1D-m": "SEAICE_GLO_PHY_L4_MY_011_020", + "METNO-GLO-SEAICE_DRIFT-NORTH-L4-NRT-OBS": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "METNO-GLO-SEAICE_DRIFT-SOUTH-L4-NRT-OBS": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-sic-north_nrt_amsr2_l4_P1D-m": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-sic-north_nrt_ssmis_l4_P1D-m": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-sic-south_nrt_amsr2_l4_P1D-m": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-sic-south_nrt_ssmis_l4_P1D-m": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-siedge_nrt_nh-P1D": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-siedge_nrt_sh-P1D": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-sitype_nrt_nh-P1D": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "osisaf_obs-si_glo_phy-sitype_nrt_sh-P1D": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_001", + "DTU-GLO-SEAICE_DRIFT-NORTH-L4-NRT-OBS": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_006", + "DTU-GLO-SEAICE_DRIFT-SOUTH-L4-NRT-OBS": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_006", + "cmems_sat-si_glo_drift_nrt_north_d": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_006", + "cmems_sat-si_glo_drift_nrt_south_d": "SEAICE_GLO_SEAICE_L4_NRT_OBSERVATIONS_011_006", + "OSISAF-GLO-SEAICE_CONC_CONT_TIMESERIES-NH-LA-OBS": "SEAICE_GLO_SEAICE_L4_REP_OBSERVATIONS_011_009", + "OSISAF-GLO-SEAICE_CONC_CONT_TIMESERIES-SH-LA-OBS": "SEAICE_GLO_SEAICE_L4_REP_OBSERVATIONS_011_009", + "OSISAF-GLO-SEAICE_CONC_TIMESERIES-NH-LA-OBS": "SEAICE_GLO_SEAICE_L4_REP_OBSERVATIONS_011_009", + "OSISAF-GLO-SEAICE_CONC_TIMESERIES-SH-LA-OBS": "SEAICE_GLO_SEAICE_L4_REP_OBSERVATIONS_011_009", + "cmems_obs-sl_blk_phy-mdt_my_l4-0.0625deg_P20Y": "SEALEVEL_BLK_PHY_MDT_L4_STATIC_008_067", + "cmems_obs-sl_eur_phy-ssh_my_al-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_alg-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_c2-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_c2n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_e1-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_e1g-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_e2-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_en-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_enn-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_g2-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_h2a-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_h2ag-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_h2b-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j1-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j1g-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j1n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j2-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j2g-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j2n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j3-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_j3n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_s3a-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_s3b-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_s6a-lr-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_tp-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_my_tpn-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_alg-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_c2n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_h2b-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_j3n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_s3a-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_s3b-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_myint_s6a-lr-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_MY_008_061", + "cmems_obs-sl_eur_phy-ssh_nrt_al-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_c2n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_h2b-l3-duacs_PT0.2S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_h2b-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_j3n-l3-duacs_PT0.2S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_j3n-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_s3a-l3-duacs_PT0.2S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_s3a-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_s3b-l3-duacs_PT0.2S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_s3b-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_s6a-hr-l3-duacs_PT0.2S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_s6a-hr-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_swon-l3-duacs_PT0.2S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_nrt_swon-l3-duacs_PT1S": "SEALEVEL_EUR_PHY_L3_NRT_008_059", + "cmems_obs-sl_eur_phy-ssh_my_allsat-l4-duacs-0.125deg_P1D": "SEALEVEL_EUR_PHY_L4_MY_008_068", + "cmems_obs-sl_eur_phy-ssh_myint_allsat-l4-duacs-0.125deg_P1D": "SEALEVEL_EUR_PHY_L4_MY_008_068", + "cmems_obs-sl_eur_phy-ssh_nrt_allsat-l4-duacs-0.125deg_P1D": "SEALEVEL_EUR_PHY_L4_NRT_008_060", + "c3s_obs-sl_glo_phy-ssh_my_twosat-l4-duacs-0.25deg_P1D": "SEALEVEL_GLO_PHY_CLIMATE_L4_MY_008_057", + "c3s_obs-sl_glo_phy-ssh_myint_twosat-l4-duacs-0.25deg_P1D": "SEALEVEL_GLO_PHY_CLIMATE_L4_MY_008_057", + "cmems_obs-sl_glo_phy-ssh_my_al-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_alg-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_c2-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_c2n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_e1-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_e1g-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_e2-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_en-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_enn-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_g2-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_h2a-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_h2ag-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_h2b-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j1-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j1g-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j1n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j2-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j2g-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j2n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j3-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_j3n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_s3a-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_s3b-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_s6a-lr-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_tp-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_my_tpn-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_alg-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_c2n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_h2b-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_j3n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_s3a-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_s3b-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_myint_s6a-lr-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_MY_008_062", + "cmems_obs-sl_glo_phy-ssh_nrt_al-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_c2n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_h2b-l3-duacs_PT0.2S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_h2b-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_j3n-l3-duacs_PT0.2S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_j3n-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_s3a-l3-duacs_PT0.2S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_s3a-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_s3b-l3-duacs_PT0.2S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_s3b-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_s6a-hr-l3-duacs_PT0.2S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_s6a-hr-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_swon-l3-duacs_PT0.2S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_nrt_swon-l3-duacs_PT1S": "SEALEVEL_GLO_PHY_L3_NRT_008_044", + "cmems_obs-sl_glo_phy-ssh_my_allsat-l4-duacs-0.25deg_P1D": "SEALEVEL_GLO_PHY_L4_MY_008_047", + "cmems_obs-sl_glo_phy-ssh_my_allsat-l4-duacs-0.25deg_P1M-m": "SEALEVEL_GLO_PHY_L4_MY_008_047", + "cmems_obs-sl_glo_phy-ssh_myint_allsat-l4-duacs-0.25deg_P1D": "SEALEVEL_GLO_PHY_L4_MY_008_047", + "cmems_obs-sl_glo_phy-ssh_myint_allsat-l4-duacs-0.25deg_P1M-m": "SEALEVEL_GLO_PHY_L4_MY_008_047", + "cmems_obs-sl_glo_phy-ssh_nrt_allsat-l4-duacs-0.25deg_P1D": "SEALEVEL_GLO_PHY_L4_NRT_008_046", + "cnes_obs-sl_glo_phy-mdt_my_0.125deg_P20Y": "SEALEVEL_GLO_PHY_MDT_008_063", + "cmems_obs-sl_glo_phy-noise_mynrt_multi-L4-duacs-0.25deg_P1Y": "SEALEVEL_GLO_PHY_NOISE_L4_STATIC_008_033", + "cmems_obs-sl_med_phy-mdt_my_l4-0.0417deg_P20Y": "SEALEVEL_MED_PHY_MDT_L4_STATIC_008_066", + "cmems_obs-sst_atl_phy_my_l3s_P1D-m": "SST_ATL_PHY_L3S_MY_010_038", + "cmems_obs-sst_atl_phy_l3s_gir_P1D-m": "SST_ATL_PHY_L3S_NRT_010_037", + "cmems_obs-sst_atl_phy_l3s_pir_P1D-m": "SST_ATL_PHY_L3S_NRT_010_037", + "cmems_obs-sst_atl_phy_l3s_pmw_P1D-m": "SST_ATL_PHY_L3S_NRT_010_037", + "cmems_obs-sst_atl_phy_nrt_l3s_P1D-m": "SST_ATL_PHY_L3S_NRT_010_037", + "IFREMER-ATL-SST-L4-NRT-OBS_FULL_TIME_SERIE": "SST_ATL_SST_L4_NRT_OBSERVATIONS_010_025", + "cmems-IFREMER-ATL-SST-L4-REP-OBS_FULL_TIME_SERIE": "SST_ATL_SST_L4_REP_OBSERVATIONS_010_026", + "cmems_obs-sst_bal_phy_my_l3s_P1D-m": "SST_BAL_PHY_L3S_MY_010_040", + "cmems_obs-sst_bal_phy-subskin_nrt_l4_PT1H-m": "SST_BAL_PHY_SUBSKIN_L4_NRT_010_034", + "DMI-BALTIC-SST-L3S-NRT-OBS_FULL_TIME_SERIE": "SST_BAL_SST_L3S_NRT_OBSERVATIONS_010_032", + "DMI-BALTIC-SST-L4-NRT-OBS_FULL_TIME_SERIE": "SST_BAL_SST_L4_NRT_OBSERVATIONS_010_007_b", + "DMI_BAL_SST_L4_REP_OBSERVATIONS_010_016": "SST_BAL_SST_L4_REP_OBSERVATIONS_010_016", + "cmems_obs-sst_bs_phy_my_l3s_P1D-m": "SST_BS_PHY_L3S_MY_010_041", + "cmems_obs-sst_blk_phy-sst_nrt_diurnal-oi-0.0625deg_PT1H-m": "SST_BS_PHY_SUBSKIN_L4_NRT_010_035", + "SST_BS_SST_L3S_NRT_OBSERVATIONS_010_013_a": "SST_BS_SST_L3S_NRT_OBSERVATIONS_010_013", + "SST_BS_SST_L3S_NRT_OBSERVATIONS_010_013_b": "SST_BS_SST_L3S_NRT_OBSERVATIONS_010_013", + "SST_BS_SSTA_L4_NRT_OBSERVATIONS_010_006_b": "SST_BS_SST_L4_NRT_OBSERVATIONS_010_006", + "SST_BS_SSTA_L4_NRT_OBSERVATIONS_010_006_d": "SST_BS_SST_L4_NRT_OBSERVATIONS_010_006", + "SST_BS_SST_L4_NRT_OBSERVATIONS_010_006_a_V2": "SST_BS_SST_L4_NRT_OBSERVATIONS_010_006", + "SST_BS_SST_L4_NRT_OBSERVATIONS_010_006_c_V2": "SST_BS_SST_L4_NRT_OBSERVATIONS_010_006", + "cmems_SST_BS_SST_L4_REP_OBSERVATIONS_010_022": "SST_BS_SST_L4_REP_OBSERVATIONS_010_022", + "cmems_obs-sst_glo_phy_my_l3s_P1D-m": "SST_GLO_PHY_L3S_MY_010_039", + "cmems_obs-sst_glo_phy_nrt_l4_P1D-m": "SST_GLO_PHY_L4_NRT_010_043", + "IFREMER-GLOB-SST-L3-NRT-OBS_FULL_TIME_SERIE": "SST_GLO_SST_L3S_NRT_OBSERVATIONS_010_010", + "cmems_obs-sst_glo_phy_l3s_gir_P1D-m": "SST_GLO_SST_L3S_NRT_OBSERVATIONS_010_010", + "cmems_obs-sst_glo_phy_l3s_pir_P1D-m": "SST_GLO_SST_L3S_NRT_OBSERVATIONS_010_010", + "cmems_obs-sst_glo_phy_l3s_pmw_P1D-m": "SST_GLO_SST_L3S_NRT_OBSERVATIONS_010_010", + "METOFFICE-GLO-SST-L4-NRT-OBS-SST-V2": "SST_GLO_SST_L4_NRT_OBSERVATIONS_010_001", + "METOFFICE-GLO-SST-L4-REP-OBS-SST": "SST_GLO_SST_L4_REP_OBSERVATIONS_010_011", + "C3S-GLO-SST-L4-REP-OBS-SST": "SST_GLO_SST_L4_REP_OBSERVATIONS_010_024", + "ESACCI-GLO-SST-L4-REP-OBS-SST": "SST_GLO_SST_L4_REP_OBSERVATIONS_010_024", + "cmems_obs-sst_med_phy_my_l3s_P1D-m": "SST_MED_PHY_L3S_MY_010_042", + "cmems_obs-sst_med_phy-sst_nrt_diurnal-oi-0.0625deg_PT1H-m": "SST_MED_PHY_SUBSKIN_L4_NRT_010_036", + "SST_MED_SST_L3S_NRT_OBSERVATIONS_010_012_a": "SST_MED_SST_L3S_NRT_OBSERVATIONS_010_012", + "SST_MED_SST_L3S_NRT_OBSERVATIONS_010_012_b": "SST_MED_SST_L3S_NRT_OBSERVATIONS_010_012", + "SST_MED_SSTA_L4_NRT_OBSERVATIONS_010_004_b": "SST_MED_SST_L4_NRT_OBSERVATIONS_010_004", + "SST_MED_SSTA_L4_NRT_OBSERVATIONS_010_004_d": "SST_MED_SST_L4_NRT_OBSERVATIONS_010_004", + "SST_MED_SST_L4_NRT_OBSERVATIONS_010_004_a_V2": "SST_MED_SST_L4_NRT_OBSERVATIONS_010_004", + "SST_MED_SST_L4_NRT_OBSERVATIONS_010_004_c_V2": "SST_MED_SST_L4_NRT_OBSERVATIONS_010_004", + "cmems_SST_MED_SST_L4_REP_OBSERVATIONS_010_021": "SST_MED_SST_L4_REP_OBSERVATIONS_010_021", + "dataset-wav-sar-l3-spc-rep-global-s1a": "WAVE_GLO_PHY_SPC_L3_MY_014_006", + "dataset-wav-sar-l3-spc-rep-global-s1b": "WAVE_GLO_PHY_SPC_L3_MY_014_006", + "cnes_obs-wave_glo_phy-spc_nrt_cfo-l3_PT10S": "WAVE_GLO_PHY_SPC_L3_NRT_014_009", + "cmems_obs-wave_glo_phy-spc_nrt_multi-l4-1deg_PT3H": "WAVE_GLO_PHY_SPC_L4_NRT_014_004", + "cci_obs-wave_glo_phy-swh_my_al-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cci_obs-wave_glo_phy-swh_my_c2-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cci_obs-wave_glo_phy-swh_my_en-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cci_obs-wave_glo_phy-swh_my_j1-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cci_obs-wave_glo_phy-swh_my_j2-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cci_obs-wave_glo_phy-swh_my_j3-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cmems_obs-wave_glo_phy-swh_my_cfo-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_MY_014_005", + "cmems_obs-wave_glo_phy-swh_nrt_al-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_c2-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_cfo-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_h2b-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_h2c-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_j3-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_s3a-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_s3b-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_s6a-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_nrt_swon-l3_PT1S": "WAVE_GLO_PHY_SWH_L3_NRT_014_001", + "cmems_obs-wave_glo_phy-swh_my_multi-l4-2deg_P1D": "WAVE_GLO_PHY_SWH_L4_MY_014_007", + "cmems_obs-wave_glo_phy-swh_nrt_multi-l4-2deg_P1D": "WAVE_GLO_PHY_SWH_L4_NRT_014_003", + "cmems_obs-wave_glo_phy-spc_nrt_cfo-l3_PT10S": "WAVE_GLO_WAV_L3_SPC_NRT_OBSERVATIONS_014_002", + "dataset-wav-sar-l3-spc-nrt-global-s1a": "WAVE_GLO_WAV_L3_SPC_NRT_OBSERVATIONS_014_002", + "dataset-wav-sar-l3-spc-nrt-global-s1b": "WAVE_GLO_WAV_L3_SPC_NRT_OBSERVATIONS_014_002", + "cmems_obs-wind_arc_phy_nrt_l3-s1a-sar-asc-0.01deg_P1D-i": "WIND_ARC_PHY_HR_L3_NRT_012_100", + "cmems_obs-wind_arc_phy_nrt_l3-s1a-sar-desc-0.01deg_P1D-i": "WIND_ARC_PHY_HR_L3_NRT_012_100", + "cmems_obs-wind_atl_phy_nrt_l3-s1a-sar-asc-0.01deg_P1D-i": "WIND_ATL_PHY_HR_L3_NRT_012_101", + "cmems_obs-wind_atl_phy_nrt_l3-s1a-sar-desc-0.01deg_P1D-i": "WIND_ATL_PHY_HR_L3_NRT_012_101", + "cmems_obs-wind_bal_phy_nrt_l3-s1a-sar-asc-0.01deg_P1D-i": "WIND_BAL_PHY_HR_L3_NRT_012_102", + "cmems_obs-wind_bal_phy_nrt_l3-s1a-sar-desc-0.01deg_P1D-i": "WIND_BAL_PHY_HR_L3_NRT_012_102", + "cmems_obs-wind_blk_phy_nrt_l3-s1a-sar-asc-0.01deg_P1D-i": "WIND_BLK_PHY_HR_L3_NRT_012_103", + "cmems_obs-wind_blk_phy_nrt_l3-s1a-sar-desc-0.01deg_P1D-i": "WIND_BLK_PHY_HR_L3_NRT_012_103", + "cmems_obs-wind_glo_phy_my_l4_P1M": "WIND_GLO_PHY_CLIMATE_L4_MY_012_003", + "cmems_obs-wind_glo_phy_my_l3-ers1-scat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-ers1-scat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-ers2-scat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-ers2-scat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopa-ascat-asc-0.125deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopa-ascat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopa-ascat-des-0.125deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopa-ascat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopb-ascat-asc-0.125deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopb-ascat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopb-ascat-des-0.125deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-metopb-ascat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-oceansat2-oscat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-oceansat2-oscat-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-oceansat2-oscat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-oceansat2-oscat-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-quikscat-seawinds-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-quikscat-seawinds-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-quikscat-seawinds-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_my_l3-quikscat-seawinds-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_MY_012_005", + "cmems_obs-wind_glo_phy_nrt_l3-hy2b-hscat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2b-hscat-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2b-hscat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2b-hscat-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2c-hscat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2c-hscat-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2c-hscat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2c-hscat-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2d-hscat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2d-hscat-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2d-hscat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-hy2d-hscat-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopa-ascat-asc-0.125deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopa-ascat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopa-ascat-des-0.125deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopa-ascat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopb-ascat-asc-0.125deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopb-ascat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopb-ascat-des-0.125deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopb-ascat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopc-ascat-asc-0.125deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopc-ascat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopc-ascat-des-0.125deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-metopc-ascat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-oceansat3-oscat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-oceansat3-oscat-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-oceansat3-oscat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-oceansat3-oscat-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-scatsat1-oscat-asc-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-scatsat1-oscat-asc-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-scatsat1-oscat-des-0.25deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_nrt_l3-scatsat1-oscat-des-0.5deg_P1D-i": "WIND_GLO_PHY_L3_NRT_012_002", + "cmems_obs-wind_glo_phy_my_l4_0.125deg_PT1H": "WIND_GLO_PHY_L4_MY_012_006", + "cmems_obs-wind_glo_phy_my_l4_0.25deg_PT1H": "WIND_GLO_PHY_L4_MY_012_006", + "cmems_obs-wind_glo_phy_nrt_l4_0.125deg_PT1H": "WIND_GLO_PHY_L4_NRT_012_004", + "cmems_obs-wind_med_phy_nrt_l3-s1a-sar-asc-0.01deg_P1D-i": "WIND_MED_PHY_HR_L3_NRT_012_104", + "cmems_obs-wind_med_phy_nrt_l3-s1a-sar-desc-0.01deg_P1D-i": "WIND_MED_PHY_HR_L3_NRT_012_104", +} diff --git a/copernicusmarine/catalogue_parser/models.py b/copernicusmarine/catalogue_parser/models.py new file mode 100644 index 00000000..1b377ed2 --- /dev/null +++ b/copernicusmarine/catalogue_parser/models.py @@ -0,0 +1,552 @@ +import re +from dataclasses import dataclass +from enum import Enum +from typing import Optional, Type, TypeVar, Union + +import pystac + +from copernicusmarine.command_line_interface.exception_handler import ( + log_exception_debug, +) +from copernicusmarine.core_functions.utils import ( + datetime_parser, + next_or_raise_exception, +) + +# Output Types definitions + +VERSION_DEFAULT = "default" +PART_DEFAULT = "default" + + +# Service types +class _ServiceName(str, Enum): + GEOSERIES = "arco-geo-series" + TIMESERIES = "arco-time-series" + FILES = "original-files" + WMTS = "wmts" + OMI_ARCO = "omi-arco" + STATIC_ARCO = "static-arco" + + +class _ServiceShortName(str, Enum): + GEOSERIES = "geoseries" + TIMESERIES = "timeseries" + FILES = "files" + WMTS = "wmts" + OMI_ARCO = "omi-arco" + STATIC_ARCO = "static-arco" + + +@dataclass(frozen=True) +class _Service: + service_name: _ServiceName + short_name: _ServiceShortName + + def aliases(self) -> list[str]: + return ( + [self.service_name.value, self.short_name.value] + if self.short_name.value != self.service_name.value + else [self.service_name.value] + ) + + def to_json_dict(self): + return { + "service_name": self.service_name.value, + "short_name": self.short_name.value, + } + + +class CopernicusMarineDatasetServiceType(_Service, Enum): + GEOSERIES = _ServiceName.GEOSERIES, _ServiceShortName.GEOSERIES + TIMESERIES = ( + _ServiceName.TIMESERIES, + _ServiceShortName.TIMESERIES, + ) + FILES = _ServiceName.FILES, _ServiceShortName.FILES + WMTS = _ServiceName.WMTS, _ServiceShortName.WMTS + OMI_ARCO = _ServiceName.OMI_ARCO, _ServiceShortName.OMI_ARCO + STATIC_ARCO = _ServiceName.STATIC_ARCO, _ServiceShortName.STATIC_ARCO + + +def _service_type_from_web_api_string( + name: str, +) -> CopernicusMarineDatasetServiceType: + class WebApi(Enum): + GEOSERIES = "timeChunked" + TIMESERIES = "geoChunked" + FILES = "native" + WMTS = "wmts" + OMI_ARCO = "omi" + STATIC_ARCO = "static" + + web_api_mapping = { + WebApi.GEOSERIES: CopernicusMarineDatasetServiceType.GEOSERIES, + WebApi.TIMESERIES: CopernicusMarineDatasetServiceType.TIMESERIES, + WebApi.FILES: CopernicusMarineDatasetServiceType.FILES, + WebApi.WMTS: CopernicusMarineDatasetServiceType.WMTS, + WebApi.OMI_ARCO: CopernicusMarineDatasetServiceType.OMI_ARCO, + WebApi.STATIC_ARCO: CopernicusMarineDatasetServiceType.STATIC_ARCO, + } + + return next_or_raise_exception( + ( + service_type + for service_web_api, service_type in web_api_mapping.items() + if service_web_api.value == name + ), + ServiceNotHandled(name), + ) + + +class ServiceNotHandled(Exception): + ... + + +# service formats +class CopernicusMarineServiceFormat(str, Enum): + ZARR = "zarr" + SQLITE = "sqlite" + + +@dataclass +class CopernicusMarineCoordinate: + coordinates_id: str + units: str + minimum_value: Optional[float] + maximum_value: Optional[float] + step: Optional[float] + values: Optional[list[Union[float, int]]] + chunking_length: Optional[int] + chunk_type: Optional[str] + chunk_reference_coordinate: Optional[int] + chunk_geometric_factor: Optional[int] + + Coordinate = TypeVar("Coordinate", bound="CopernicusMarineCoordinate") + + @classmethod + def from_metadata_item( + cls: Type[Coordinate], + variable_id: str, + dimension: str, + dimension_metadata: dict, + arco_data_metadata_producer_valid_start_date: Optional[str], + ) -> Coordinate: + coordinates_info = dimension_metadata.get("coords", {}) + if ( + arco_data_metadata_producer_valid_start_date + and dimension == "time" + ): + minimum_value = ( + CopernicusMarineCoordinate._format_admp_valid_start_date( + arco_data_metadata_producer_valid_start_date, + to_timestamp=isinstance(coordinates_info.get("min"), int), + ) + ) + else: + minimum_value = coordinates_info.get("min") + chunking_length = dimension_metadata.get("chunkLen") + if isinstance(chunking_length, dict): + chunking_length = chunking_length.get(variable_id) + + coordinate = cls( + coordinates_id=dimension, + units=dimension_metadata.get("units") or "", + minimum_value=minimum_value, # type: ignore + maximum_value=coordinates_info.get("max"), + step=coordinates_info.get("step"), + values=coordinates_info.get("values"), + chunking_length=chunking_length, + chunk_type=dimension_metadata.get("chunkType"), + chunk_reference_coordinate=dimension_metadata.get("chunkRefCoord"), + chunk_geometric_factor=dimension_metadata.get( + "chunkGeometricFactor", {} + ).get(variable_id), + ) + if dimension == "elevation": + coordinate._convert_elevation_to_depth() + return coordinate + + @staticmethod + def _format_admp_valid_start_date( + arco_data_metadata_producer_valid_start_date: str, + to_timestamp: bool = False, + ) -> Union[str, int]: + if to_timestamp: + return int( + datetime_parser( + arco_data_metadata_producer_valid_start_date.split(".")[0] + ).timestamp() + * 1000 + ) + return arco_data_metadata_producer_valid_start_date.split(".")[0] + + def _convert_elevation_to_depth(self): + self.coordinates_id = "depth" + minimum_elevation = self.minimum_value + maximum_elevation = self.maximum_value + if minimum_elevation is not None: + self.maximum_value = -minimum_elevation + else: + self.maximum_value = None + if maximum_elevation is not None: + self.minimum_value = -maximum_elevation + else: + self.minimum_value = None + if self.values is not None: + self.values = [-value for value in self.values] + + +@dataclass +class CopernicusMarineVariable: + short_name: str + standard_name: str + units: str + bbox: Optional[list[float]] + coordinates: list[CopernicusMarineCoordinate] + + Variable = TypeVar("Variable", bound="CopernicusMarineVariable") + + @classmethod + def from_metadata_item( + cls: Type[Variable], + metadata_item: pystac.Item, + asset: pystac.Asset, + variable_id: str, + bbox: Optional[list[float]], + ) -> Variable: + cube_variables = metadata_item.properties["cube:variables"] + cube_variable = cube_variables[variable_id] + + # to get coordinates + extra_fields_asset = asset.extra_fields + dimensions = extra_fields_asset.get("viewDims") or {} + return cls( + short_name=variable_id, + standard_name=cube_variable["standardName"], + units=cube_variable.get("unit") or "", + bbox=bbox, + coordinates=[ + CopernicusMarineCoordinate.from_metadata_item( + variable_id, + dimension, + dimension_metadata, + metadata_item.properties.get("admp_valid_start_date"), + ) + for dimension, dimension_metadata in dimensions.items() + ], + ) + + +@dataclass +class CopernicusMarineService: + service_type: CopernicusMarineDatasetServiceType + service_format: Optional[CopernicusMarineServiceFormat] + uri: str + variables: list[CopernicusMarineVariable] + + Service = TypeVar("Service", bound="CopernicusMarineService") + + @classmethod + def from_metadata_item( + cls: Type[Service], + metadata_item: pystac.Item, + service_name: str, + asset: pystac.Asset, + ) -> Optional[Service]: + try: + service_uri = asset.get_absolute_href() + if not service_uri: + raise ServiceNotHandled(service_name) + service_type = _service_type_from_web_api_string(service_name) + service_format = None + admp_in_preparation = metadata_item.properties.get( + "admp_in_preparation" + ) + if asset.media_type and "zarr" in asset.media_type: + service_format = CopernicusMarineServiceFormat.ZARR + elif asset.media_type and "sqlite3" in asset.media_type: + service_format = CopernicusMarineServiceFormat.SQLITE + + if not service_uri.endswith("/"): + if admp_in_preparation and ( + service_type + == CopernicusMarineDatasetServiceType.GEOSERIES + or service_type + == CopernicusMarineDatasetServiceType.TIMESERIES + ): + return None + else: + bbox = metadata_item.bbox + return cls( + service_type=service_type, + uri=service_uri, + variables=[ + CopernicusMarineVariable.from_metadata_item( + metadata_item, asset, var_cube["id"], bbox + ) + for var_cube in metadata_item.properties[ + "cube:variables" + ].values() + ], + service_format=service_format, + ) + return None + except ServiceNotHandled as service_not_handled: + log_exception_debug(service_not_handled) + return None + + +@dataclass +class CopernicusMarineVersionPart: + name: str + services: list[CopernicusMarineService] + retired_date: Optional[str] + released_date: Optional[str] + + VersionPart = TypeVar("VersionPart", bound="CopernicusMarineVersionPart") + + @classmethod + def from_metadata_item( + cls: Type[VersionPart], metadata_item: pystac.Item, part_name: str + ) -> Optional[VersionPart]: + retired_date = metadata_item.properties.get("admp_retired_date") + released_date = metadata_item.properties.get("admp_released_date") + if retired_date and datetime_parser(retired_date) < datetime_parser( + "now" + ): + return None + services = [ + service + for metadata_service_name, asset in metadata_item.get_assets().items() + if ( + service := CopernicusMarineService.from_metadata_item( + metadata_item, + metadata_service_name, + asset, + ) + ) + ] + if not services: + return None + services = services + return cls( + name=part_name, + services=services, + retired_date=retired_date, + released_date=released_date, + ) + + def get_service_by_service_type( + self, service_type: CopernicusMarineDatasetServiceType + ): + return next( + service + for service in self.services + if service.service_type == service_type + ) + + +@dataclass +class CopernicusMarineDatasetVersion: + label: str + parts: list[CopernicusMarineVersionPart] + + def get_part( + self, force_part: Optional[str] + ) -> CopernicusMarineVersionPart: + wanted_part = force_part or PART_DEFAULT + for part in self.parts: + if part.name == wanted_part: + return part + elif not force_part: + return part + raise dataset_version_part_not_found_exception(self) + + def sort_parts(self) -> tuple[Optional[str], Optional[str]]: + not_released_parts = { + part.name + for part in self.parts + if part.released_date + and datetime_parser(part.released_date) > datetime_parser("now") + } + will_be_retired_parts = { + part.name: datetime_parser(part.retired_date).timestamp() + for part in self.parts + if part.retired_date + } + max_retired_timestamp = 0 + if will_be_retired_parts: + max_retired_timestamp = max(will_be_retired_parts.values()) + 1 + self.parts = sorted( + self.parts, + key=lambda x: ( + x.name in not_released_parts, + max_retired_timestamp + - will_be_retired_parts.get(x.name, max_retired_timestamp), + -(x.name == PART_DEFAULT), + -(x.name == "latest"), # for INSITU datasets + -(x.name == "bathy"), # for STATIC datasets + x.name, + ), + ) + return self.parts[0].released_date, self.parts[0].retired_date + + +@dataclass +class CopernicusMarineProductDataset: + dataset_id: str + dataset_name: str + versions: list[CopernicusMarineDatasetVersion] + + def get_version( + self, force_version: Optional[str] + ) -> CopernicusMarineDatasetVersion: + wanted_version = force_version or VERSION_DEFAULT + for version in self.versions: + if version.label == wanted_version: + return version + elif not force_version: + return version + raise dataset_version_not_found_exception(self) + + def sort_versions(self) -> None: + not_released_versions: set[str] = set() + retired_dates = {} + for version in self.versions: + released_date, retired_date = version.sort_parts() + if released_date and datetime_parser( + released_date + ) > datetime_parser("now"): + not_released_versions.add(version.label) + if retired_date: + retired_dates[version.label] = retired_date + + self.versions = sorted( + self.versions, + key=lambda x: ( + -(x.label in not_released_versions), + retired_dates.get(x.label, "9999-12-31"), + -(x.label == VERSION_DEFAULT), + x.label, + ), + reverse=True, + ) + + def parse_dataset_metadata_items( + self, metadata_items: list[pystac.Item] + ) -> None: + all_versions = set() + for metadata_item in metadata_items: + ( + _, + dataset_version, + dataset_part, + ) = get_version_and_part_from_full_dataset_id(metadata_item.id) + part = CopernicusMarineVersionPart.from_metadata_item( + metadata_item, dataset_part + ) + if not part: + continue + if dataset_version in all_versions: + for version in self.versions: + if version.label == dataset_version: + version.parts.append(part) + break + else: + all_versions.add(dataset_version) + version = CopernicusMarineDatasetVersion( + label=dataset_version, parts=[part] + ) + self.versions.append(version) + + +@dataclass +class CopernicusMarineProduct: + title: str + product_id: str + thumbnail_url: str + description: str + digital_object_identifier: Optional[str] + sources: list[str] + processing_level: Optional[str] + production_center: str + keywords: Optional[list[str]] + datasets: list[CopernicusMarineProductDataset] + + +@dataclass +class CopernicusMarineCatalogue: + products: list[CopernicusMarineProduct] + + def filter_only_official_versions_and_parts(self): + products_to_remove = [] + for product in self.products: + datasets_to_remove = [] + for dataset in product.datasets: + latest_version = dataset.versions[0] + parts_to_remove = [] + for part in latest_version.parts: + if part.released_date and datetime_parser( + part.released_date + ) > datetime_parser("now"): + parts_to_remove.append(part) + for part_to_remove in parts_to_remove: + latest_version.parts.remove(part_to_remove) + if not latest_version.parts: + datasets_to_remove.append(dataset) + else: + dataset.versions = [latest_version] + for dataset_to_remove in datasets_to_remove: + product.datasets.remove(dataset_to_remove) + if not product.datasets: + products_to_remove.append(product) + for product_to_remove in products_to_remove: + self.products.remove(product_to_remove) + + +# Errors +class DatasetVersionPartNotFound(Exception): + ... + + +class DatasetVersionNotFound(Exception): + ... + + +def dataset_version_part_not_found_exception( + version: CopernicusMarineDatasetVersion, +) -> DatasetVersionPartNotFound: + return DatasetVersionPartNotFound( + f"No part found for version {version.label}" + ) + + +def dataset_version_not_found_exception( + dataset: CopernicusMarineProductDataset, +) -> DatasetVersionNotFound: + return DatasetVersionNotFound( + f"No version found for dataset {dataset.dataset_id}" + ) + + +REGEX_PATTERN_DATE_YYYYMM = r"[12]\d{3}(0[1-9]|1[0-2])" +PART_SEPARATOR = "--ext--" + + +def get_version_and_part_from_full_dataset_id( + full_dataset_id: str, +) -> tuple[str, str, str]: + if PART_SEPARATOR in full_dataset_id: + name_with_maybe_version, part = full_dataset_id.split(PART_SEPARATOR) + else: + name_with_maybe_version = full_dataset_id + part = PART_DEFAULT + pattern = rf"^(.*?)(?:_({REGEX_PATTERN_DATE_YYYYMM}))?$" + match = re.match(pattern, name_with_maybe_version) + if match: + dataset_name = match.group(1) + version = match.group(2) or VERSION_DEFAULT + else: + raise Exception(f"Could not parse dataset id: {full_dataset_id}") + return dataset_name, version, part diff --git a/copernicusmarine/catalogue_parser/request_structure.py b/copernicusmarine/catalogue_parser/request_structure.py index c3b893c1..6e90ec89 100644 --- a/copernicusmarine/catalogue_parser/request_structure.py +++ b/copernicusmarine/catalogue_parser/request_structure.py @@ -45,8 +45,8 @@ class DatasetTimeAndGeographicalSubset: @dataclass class SubsetRequest: + dataset_id: str dataset_url: Optional[str] = None - dataset_id: Optional[str] = None force_dataset_version: Optional[str] = None force_dataset_part: Optional[str] = None variables: Optional[List[str]] = None @@ -112,10 +112,6 @@ def enforce_types(self): type_enforced_dict[key] = new_value self.__dict__.update(type_enforced_dict) - def from_file(self, filepath: pathlib.Path): - self.update(subset_request_from_file(filepath).__dict__) - return self - def get_time_and_geographical_subset( self, ) -> DatasetTimeAndGeographicalSubset: @@ -128,29 +124,26 @@ def get_time_and_geographical_subset( end_datetime=self.end_datetime, ) + def from_file(self, filepath: pathlib.Path): + json_file = open(filepath) + json_content = load(json_file) + + json_with_deprecated_options_replace = {} + + for key, val in json_content.items(): + if key in DEPRECATED_OPTIONS: + deprecated_option = DEPRECATED_OPTIONS[key] + json_with_deprecated_options_replace[ + deprecated_option.new_name + ] = val + elif key in MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS: + new_key = MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS[key] + json_with_deprecated_options_replace[new_key] = val + else: + json_with_deprecated_options_replace[key] = val -def subset_request_from_file(filepath: pathlib.Path) -> SubsetRequest: - json_file = open(filepath) - json_content = load(json_file) - - json_with_deprecated_options_replace = {} - - for key, val in json_content.items(): - if key in DEPRECATED_OPTIONS: - deprecated_option = DEPRECATED_OPTIONS[key] - json_with_deprecated_options_replace[ - deprecated_option.new_name - ] = val - elif key in MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS: - new_key = MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS[key] - json_with_deprecated_options_replace[new_key] = val - else: - json_with_deprecated_options_replace[key] = val - - subset_request = SubsetRequest() - subset_request.__dict__.update(json_with_deprecated_options_replace) - subset_request.enforce_types() - return subset_request + self.__dict__.update(json_with_deprecated_options_replace) + self.enforce_types() def convert_motu_api_request_to_structure( @@ -172,6 +165,7 @@ def convert_motu_api_request_to_structure( else: motu_api_request_dict[arg] = value subset_request = SubsetRequest( + dataset_id="", output_directory=pathlib.Path("."), force_download=False, output_filename=None, @@ -198,8 +192,8 @@ def convert_motu_api_request_to_structure( @dataclass class GetRequest: + dataset_id: str dataset_url: Optional[str] = None - dataset_id: Optional[str] = None force_dataset_version: Optional[str] = None force_dataset_part: Optional[str] = None no_directories: bool = False @@ -241,43 +235,34 @@ def enforce_types(self): self.__dict__.update(type_enforced_dict) def from_file(self, filepath: pathlib.Path): - self = get_request_from_file(filepath) - logger.info(filepath) - return self - - -def get_request_from_file(filepath: pathlib.Path) -> GetRequest: - json_file = load(open(filepath)) - json_with_mapped_options = {} - for key, val in json_file.items(): - if key in MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS: - new_key = MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS[key] - json_with_mapped_options[new_key] = val - else: - json_with_mapped_options[key] = val - get_request = GetRequest() - get_request.__dict__.update(json_with_mapped_options) - get_request.enforce_types() - full_regex = get_request.regex - if get_request.filter: - filter_regex = filter_to_regex(get_request.filter) - full_regex = overload_regex_with_additionnal_filter( - filter_regex, full_regex - ) - if get_request.file_list: - file_list_regex = file_list_to_regex(get_request.file_list) - full_regex = overload_regex_with_additionnal_filter( - file_list_regex, full_regex - ) - get_request.regex = full_regex - - return get_request + json_file = load(open(filepath)) + json_with_mapped_options = {} + for key, val in json_file.items(): + if key in MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS: + new_key = MAPPING_REQUEST_FILES_AND_REQUEST_OPTIONS[key] + json_with_mapped_options[new_key] = val + else: + json_with_mapped_options[key] = val + self.__dict__.update(json_with_mapped_options) + self.enforce_types() + full_regex = self.regex + if self.filter: + filter_regex = filter_to_regex(self.filter) + full_regex = overload_regex_with_additionnal_filter( + filter_regex, full_regex + ) + if self.file_list: + file_list_regex = file_list_to_regex(self.file_list) + full_regex = overload_regex_with_additionnal_filter( + file_list_regex, full_regex + ) + self.regex = full_regex @dataclass class LoadRequest: + dataset_id: str dataset_url: Optional[str] = None - dataset_id: Optional[str] = None force_dataset_version: Optional[str] = None force_dataset_part: Optional[str] = None username: Optional[str] = None @@ -293,8 +278,6 @@ class LoadRequest: subset_method: SubsetMethod = DEFAULT_SUBSET_METHOD force_service: Optional[str] = None credentials_file: Optional[pathlib.Path] = None - overwrite_metadata_cache: bool = False - no_metadata_cache: bool = False def get_time_and_geographical_subset( self, diff --git a/copernicusmarine/command_line_interface/group_describe.py b/copernicusmarine/command_line_interface/group_describe.py index 47f86ab2..3abe2bfa 100644 --- a/copernicusmarine/command_line_interface/group_describe.py +++ b/copernicusmarine/command_line_interface/group_describe.py @@ -5,10 +5,7 @@ from copernicusmarine.command_line_interface.exception_handler import ( log_exception_and_exit, ) -from copernicusmarine.command_line_interface.utils import ( - MutuallyExclusiveOption, - tqdm_disable_option, -) +from copernicusmarine.command_line_interface.utils import tqdm_disable_option from copernicusmarine.core_functions.deprecated import ( DeprecatedClickOption, DeprecatedClickOptionsCommand, @@ -99,24 +96,6 @@ def cli_group_describe() -> None: help="Filter catalogue output. Returns products with attributes " "matching a string token.", ) -@click.option( - "--overwrite-metadata-cache", - cls=MutuallyExclusiveOption, - type=bool, - is_flag=True, - default=False, - help="Force to refresh the catalogue by overwriting the local cache.", - mutually_exclusive=["no_metadata_cache"], -) -@click.option( - "--no-metadata-cache", - cls=MutuallyExclusiveOption, - type=bool, - is_flag=True, - default=False, - help="Bypass the use of cache.", - mutually_exclusive=["overwrite_metadata_cache"], -) @tqdm_disable_option @click.option( "--log-level", @@ -142,8 +121,6 @@ def describe( include_versions: bool, include_all: bool, contains: list[str], - overwrite_metadata_cache: bool, - no_metadata_cache: bool, disable_progress_bar: bool, log_level: str, staging: bool, @@ -169,8 +146,6 @@ def describe( include_keywords=include_keywords, include_versions=include_versions, contains=contains, - overwrite_metadata_cache=overwrite_metadata_cache, - no_metadata_cache=no_metadata_cache, disable_progress_bar=disable_progress_bar, staging=staging, ) diff --git a/copernicusmarine/command_line_interface/group_get.py b/copernicusmarine/command_line_interface/group_get.py index eec1ef79..d01e8e17 100644 --- a/copernicusmarine/command_line_interface/group_get.py +++ b/copernicusmarine/command_line_interface/group_get.py @@ -44,7 +44,7 @@ def cli_group_get() -> None: help=""" Download originally produced data files. - Either one of --dataset-id or --dataset-url is required (can be found via the "describe" command). + --dataset-id is required (can be found via the "describe" command). The function fetches the files recursively if a folder path is passed as URL. When provided a datasetID, all the files in the corresponding folder will be downloaded if none of the --filter or --regex options is specified. """, # noqa @@ -55,16 +55,11 @@ def cli_group_get() -> None: copernicusmarine get -nd -o data_folder --dataset-id cmems_mod_nws_bgc-pft_myint_7km-3D-diato_P1M-m """, # noqa ) -@click.option( - "--dataset-url", - "-u", - type=str, - help="URL to the data files.", -) @click.option( "--dataset-id", "-i", type=str, + default=None, help="The datasetID.", ) @force_dataset_version_option @@ -159,24 +154,6 @@ def cli_group_get() -> None: "The file MUST follow the structure of dataclass 'GetRequest'." " For more information please refer to the README.", ) -@click.option( - "--overwrite-metadata-cache", - cls=MutuallyExclusiveOption, - type=bool, - is_flag=True, - default=False, - help="Force to refresh the catalogue by overwriting the local cache.", - mutually_exclusive=["no_metadata_cache"], -) -@click.option( - "--no-metadata-cache", - cls=MutuallyExclusiveOption, - type=bool, - is_flag=True, - default=False, - help="Bypass the use of cache.", - mutually_exclusive=["overwrite_metadata_cache"], -) @click.option( "--filter", "--filter-with-globbing-pattern", @@ -268,7 +245,6 @@ def cli_group_get() -> None: ) @log_exception_and_exit def get( - dataset_url: Optional[str], dataset_id: Optional[str], dataset_version: Optional[str], dataset_part: Optional[str], @@ -283,8 +259,6 @@ def get( create_template: bool, request_file: Optional[pathlib.Path], service: Optional[str], - overwrite_metadata_cache: bool, - no_metadata_cache: bool, filter: Optional[str], regex: Optional[str], file_list: Optional[pathlib.Path], @@ -314,7 +288,6 @@ def get( return return get_function( - dataset_url=dataset_url, dataset_id=dataset_id, force_dataset_version=dataset_version, force_dataset_part=dataset_part, @@ -328,8 +301,6 @@ def get( overwrite_output_data=overwrite_output_data, request_file=request_file, force_service=service, - overwrite_metadata_cache=overwrite_metadata_cache, - no_metadata_cache=no_metadata_cache, filter=filter, regex=regex, file_list_path=file_list, diff --git a/copernicusmarine/command_line_interface/group_login.py b/copernicusmarine/command_line_interface/group_login.py index cb787329..c8bee683 100644 --- a/copernicusmarine/command_line_interface/group_login.py +++ b/copernicusmarine/command_line_interface/group_login.py @@ -7,8 +7,10 @@ from copernicusmarine.command_line_interface.exception_handler import ( log_exception_and_exit, ) +from copernicusmarine.core_functions.credentials_utils import ( + DEFAULT_CLIENT_BASE_DIRECTORY, +) from copernicusmarine.core_functions.login import login_function -from copernicusmarine.core_functions.utils import DEFAULT_CLIENT_BASE_DIRECTORY logger = logging.getLogger("copernicus_marine_root_logger") diff --git a/copernicusmarine/command_line_interface/group_subset.py b/copernicusmarine/command_line_interface/group_subset.py index 83745fef..6d9d0a3f 100644 --- a/copernicusmarine/command_line_interface/group_subset.py +++ b/copernicusmarine/command_line_interface/group_subset.py @@ -9,7 +9,6 @@ log_exception_and_exit, ) from copernicusmarine.command_line_interface.utils import ( - MutuallyExclusiveOption, assert_cli_args_are_not_set_except_create_template, force_dataset_part_option, force_dataset_version_option, @@ -54,7 +53,7 @@ def cli_group_subset() -> None: help=""" Download subsets of datasets as NetCDF files or Zarr stores. - Either one of --dataset-id or --dataset-url is required (can be found via the "describe" command). + --dataset-id is required (can be found via the "describe" command). The argument values passed individually through the CLI take precedence over the values from the --motu-api-request option, which takes precedence over the ones from the --request-file option. """, # noqa @@ -74,16 +73,11 @@ def cli_group_subset() -> None: copernicusmarine subset -i cmems_mod_glo_phy-thetao_anfc_0.083deg_PT6H-i -v thetao -t 2022-01-01T00:00:00 -T 2022-12-31T23:59:59 -x -6.17 -X -5.08 -y 35.75 -Y 36.30 -z 0.0 -Z 5.0 """, # noqa ) -@click.option( - "--dataset-url", - "-u", - type=str, - help="The full dataset URL.", -) @click.option( "--dataset-id", "-i", type=str, + default=None, help="The datasetID.", ) @force_dataset_version_option @@ -297,24 +291,6 @@ def cli_group_subset() -> None: "quotes ' in the request." ), ) -@click.option( - "--overwrite-metadata-cache", - cls=MutuallyExclusiveOption, - type=bool, - is_flag=True, - default=False, - help="Force to refresh the catalogue by overwriting the local cache.", - mutually_exclusive=["no_metadata_cache"], -) -@click.option( - "--no-metadata-cache", - cls=MutuallyExclusiveOption, - type=bool, - is_flag=True, - default=False, - help="Bypass the use of cache.", - mutually_exclusive=["overwrite_metadata_cache"], -) @tqdm_disable_option @click.option( "--log-level", @@ -361,8 +337,7 @@ def cli_group_subset() -> None: ) @log_exception_and_exit def subset( - dataset_url: Optional[str], - dataset_id: Optional[str], + dataset_id: str, dataset_version: Optional[str], dataset_part: Optional[str], username: Optional[str], @@ -391,8 +366,6 @@ def subset( motu_api_request: Optional[str], force_download: bool, overwrite_output_data: bool, - overwrite_metadata_cache: bool, - no_metadata_cache: bool, disable_progress_bar: bool, log_level: str, staging: bool = False, @@ -414,7 +387,6 @@ def subset( return subset_function( - dataset_url, dataset_id, dataset_version, dataset_part, @@ -440,8 +412,6 @@ def subset( motu_api_request, force_download, overwrite_output_data, - overwrite_metadata_cache, - no_metadata_cache, disable_progress_bar, staging, netcdf_compression_enabled, diff --git a/copernicusmarine/core_functions/credentials_utils.py b/copernicusmarine/core_functions/credentials_utils.py index a554f48d..92987dae 100644 --- a/copernicusmarine/core_functions/credentials_utils.py +++ b/copernicusmarine/core_functions/credentials_utils.py @@ -2,7 +2,6 @@ import configparser import logging import pathlib -from datetime import timedelta from netrc import netrc from platform import system from typing import Literal, Optional, Tuple @@ -10,26 +9,31 @@ import click import lxml.html import requests -from cachier.core import cachier from copernicusmarine.core_functions.environment_variables import ( + COPERNICUSMARINE_CREDENTIALS_DIRECTORY, COPERNICUSMARINE_SERVICE_PASSWORD, COPERNICUSMARINE_SERVICE_USERNAME, ) from copernicusmarine.core_functions.sessions import ( get_configured_requests_session, ) -from copernicusmarine.core_functions.utils import ( - CACHE_BASE_DIRECTORY, - DEFAULT_CLIENT_BASE_DIRECTORY, -) logger = logging.getLogger("copernicus_marine_root_logger") +USER_DEFINED_CACHE_DIRECTORY: str = ( + COPERNICUSMARINE_CREDENTIALS_DIRECTORY or "" +) +DEFAULT_CLIENT_BASE_DIRECTORY: pathlib.Path = ( + pathlib.Path(USER_DEFINED_CACHE_DIRECTORY) + if USER_DEFINED_CACHE_DIRECTORY + else pathlib.Path.home() +) / ".copernicusmarine" DEFAULT_CLIENT_CREDENTIALS_FILENAME = ".copernicusmarine-credentials" DEFAULT_CLIENT_CREDENTIALS_FILEPATH = ( DEFAULT_CLIENT_BASE_DIRECTORY / DEFAULT_CLIENT_CREDENTIALS_FILENAME ) +# TODO: handle cache of the credentials without cachier class CredentialCannotBeNone(Exception): @@ -94,10 +98,10 @@ def _retrieve_credential_from_environment_variable( credential_type: Literal["username", "password"] ) -> Optional[str]: if credential_type == "username": - logger.debug("username loaded from environment variable") + logger.debug("Tried to load username from environment variable") return COPERNICUSMARINE_SERVICE_USERNAME if credential_type == "password": - logger.debug("password loaded from environment variable") + logger.debug("Tried to load password from environment variable") return COPERNICUSMARINE_SERVICE_PASSWORD @@ -255,12 +259,11 @@ def _check_credentials_with_cas(username: str, password: str) -> bool: return login_success -@cachier(stale_after=timedelta(hours=48), cache_dir=CACHE_BASE_DIRECTORY) def _are_copernicus_marine_credentials_valid( username: str, password: str ) -> Optional[bool]: number_of_retry = 3 - user_is_active = None # Not cached by cachier + user_is_active = None while (user_is_active not in [True, False]) and number_of_retry > 0: try: user_is_active = _check_credentials_with_cas( @@ -310,14 +313,14 @@ def get_and_check_username_password( username: Optional[str], password: Optional[str], credentials_file: Optional[pathlib.Path], - no_metadata_cache: bool, ) -> Tuple[str, str]: username, password = get_username_password( username=username, password=password, credentials_file=credentials_file ) copernicus_marine_credentials_are_valid = ( _are_copernicus_marine_credentials_valid( - username, password, ignore_cache=no_metadata_cache + username, + password, ) ) if not copernicus_marine_credentials_are_valid: @@ -380,9 +383,7 @@ def credentials_file_builder( password, "password", True ) copernicus_marine_credentials_are_valid = ( - _are_copernicus_marine_credentials_valid( - username, password, ignore_cache=False - ) + _are_copernicus_marine_credentials_valid(username, password) ) if copernicus_marine_credentials_are_valid: configuration_file = create_copernicusmarine_configuration_file( diff --git a/copernicusmarine/core_functions/describe.py b/copernicusmarine/core_functions/describe.py index 921942a8..b62bd091 100644 --- a/copernicusmarine/core_functions/describe.py +++ b/copernicusmarine/core_functions/describe.py @@ -2,14 +2,12 @@ import logging from copernicusmarine.catalogue_parser.catalogue_parser import ( - CopernicusMarineCatalogue, - CopernicusMarineDatasetServiceType, filter_catalogue_with_strings, parse_catalogue, ) -from copernicusmarine.core_functions.utils import ( - create_cache_directory, - delete_cache_folder, +from copernicusmarine.catalogue_parser.models import ( + CopernicusMarineCatalogue, + CopernicusMarineDatasetServiceType, ) from copernicusmarine.core_functions.versions_verifier import VersionVerifier @@ -22,8 +20,6 @@ def describe_function( include_keywords: bool, include_versions: bool, contains: list[str], - overwrite_metadata_cache: bool, - no_metadata_cache: bool, disable_progress_bar: bool, staging: bool, ) -> str: @@ -35,14 +31,7 @@ def describe_function( "Data will come from the staging environment." ) - if overwrite_metadata_cache: - delete_cache_folder(quiet=True) - - if not no_metadata_cache: - create_cache_directory() - base_catalogue: CopernicusMarineCatalogue = parse_catalogue( - no_metadata_cache=no_metadata_cache, disable_progress_bar=disable_progress_bar, staging=staging, ) diff --git a/copernicusmarine/core_functions/environment_variables.py b/copernicusmarine/core_functions/environment_variables.py index ee22f9e6..d5181bd7 100644 --- a/copernicusmarine/core_functions/environment_variables.py +++ b/copernicusmarine/core_functions/environment_variables.py @@ -20,8 +20,8 @@ "Please use COPERNICUSMARINE_SERVICE_PASSWORD instead." ) -COPERNICUSMARINE_CACHE_DIRECTORY = os.getenv( - "COPERNICUSMARINE_CACHE_DIRECTORY", "" +COPERNICUSMARINE_CREDENTIALS_DIRECTORY = os.getenv( + "COPERNICUSMARINE_CREDENTIALS_DIRECTORY" ) COPERNICUSMARINE_MAX_CONCURRENT_REQUESTS = os.getenv( diff --git a/copernicusmarine/core_functions/get.py b/copernicusmarine/core_functions/get.py index 196b2ef9..5e71d87f 100644 --- a/copernicusmarine/core_functions/get.py +++ b/copernicusmarine/core_functions/get.py @@ -4,11 +4,9 @@ import pathlib from typing import List, Optional -from copernicusmarine.catalogue_parser.catalogue_parser import parse_catalogue from copernicusmarine.catalogue_parser.request_structure import ( GetRequest, filter_to_regex, - get_request_from_file, overload_regex_with_additionnal_filter, ) from copernicusmarine.core_functions.credentials_utils import ( @@ -19,11 +17,7 @@ RetrievalService, get_retrieval_service, ) -from copernicusmarine.core_functions.utils import ( - create_cache_directory, - delete_cache_folder, - get_unique_filename, -) +from copernicusmarine.core_functions.utils import get_unique_filename from copernicusmarine.core_functions.versions_verifier import VersionVerifier from copernicusmarine.download_functions.download_original_files import ( download_original_files, @@ -33,7 +27,6 @@ def get_function( - dataset_url: Optional[str], dataset_id: Optional[str], force_dataset_version: Optional[str], force_dataset_part: Optional[str], @@ -47,8 +40,6 @@ def get_function( overwrite_output_data: bool, request_file: Optional[pathlib.Path], force_service: Optional[str], - overwrite_metadata_cache: bool, - no_metadata_cache: bool, filter: Optional[str], regex: Optional[str], file_list_path: Optional[pathlib.Path], @@ -67,24 +58,18 @@ def get_function( "Data will come from the staging environment." ) - if overwrite_metadata_cache: - delete_cache_folder() - - get_request = GetRequest() + get_request = GetRequest(dataset_id=dataset_id or "") if request_file: - get_request = get_request_from_file(request_file) + get_request.from_file(request_file) + if not get_request.dataset_id: + raise ValueError("Please provide a dataset id for a get request.") request_update_dict = { - "dataset_url": dataset_url, - "dataset_id": dataset_id, "force_dataset_version": force_dataset_version, "output_directory": output_directory, "force_service": force_service, } get_request.update(request_update_dict) - if not no_metadata_cache: - create_cache_directory() - # Specific treatment for default values: # In order to not overload arguments with default values # TODO is this really useful? @@ -141,7 +126,6 @@ def get_function( get_request=get_request, create_file_list=create_file_list, credentials_file=credentials_file, - no_metadata_cache=no_metadata_cache, disable_progress_bar=disable_progress_bar, staging=staging, ) @@ -153,32 +137,24 @@ def _run_get_request( get_request: GetRequest, create_file_list: Optional[str], credentials_file: Optional[pathlib.Path], - no_metadata_cache: bool, disable_progress_bar: bool, staging: bool = False, ) -> List[pathlib.Path]: + logger.debug("Checking username and password...") username, password = get_and_check_username_password( - username, - password, - credentials_file, - no_metadata_cache=no_metadata_cache, + username, password, credentials_file ) + logger.debug("Checking dataset metadata...") - catalogue = parse_catalogue( - no_metadata_cache=no_metadata_cache, - disable_progress_bar=disable_progress_bar, - staging=staging, - ) retrieval_service: RetrievalService = get_retrieval_service( - catalogue, get_request.dataset_id, - get_request.dataset_url, get_request.force_dataset_version, get_request.force_dataset_part, get_request.force_service, CommandType.GET, get_request.index_parts, dataset_sync=get_request.sync, + staging=staging, ) get_request.dataset_url = retrieval_service.uri logger.info( @@ -221,8 +197,6 @@ def create_get_template() -> None: "index_parts": False, "disable_progress_bar": False, "overwrite_output_data": False, - "overwrite_metadata_cache": False, - "no_metadata_cache": False, "log_level": "INFO", }, output_file, diff --git a/copernicusmarine/core_functions/services_utils.py b/copernicusmarine/core_functions/services_utils.py index f0c796d5..5e2ad010 100644 --- a/copernicusmarine/core_functions/services_utils.py +++ b/copernicusmarine/core_functions/services_utils.py @@ -1,11 +1,14 @@ +import asyncio import logging from dataclasses import dataclass from enum import Enum from itertools import chain -from typing import List, Literal, Optional, Tuple, Union +from typing import List, Literal, Optional, Union from copernicusmarine.catalogue_parser.catalogue_parser import ( - CopernicusMarineCatalogue, + get_dataset_metadata, +) +from copernicusmarine.catalogue_parser.models import ( CopernicusMarineDatasetServiceType, CopernicusMarineDatasetVersion, CopernicusMarineProductDataset, @@ -258,39 +261,6 @@ def _select_service_by_priority( return first_available_service -def parse_dataset_id_and_service_and_suffix_path_from_url( - catalogue: CopernicusMarineCatalogue, - dataset_url: Optional[str], -) -> Tuple[str, CopernicusMarineDatasetServiceType, str,]: - if dataset_url is None: - syntax_error = SyntaxError( - "Must specify at least one of " - "'dataset_url' or 'dataset_id' options" - ) - raise syntax_error - return next_or_raise_exception( - ( - ( - dataset.dataset_id, - service.service_type, - dataset_url.split(service.uri)[1], - ) - for product in catalogue.products - for dataset in product.datasets - for dataset_version in dataset.versions - for dataset_part in dataset_version.parts - for service in dataset_part.services - if dataset_url.startswith(service.uri) - ), - KeyError( - f"The requested dataset URL '{dataset_url}' " - "was not found in the catalogue, " - "you can use 'copernicusmarine describe --include-datasets " - "--contains ' to find datasets" - ), - ) - - @dataclass class RetrievalService: dataset_id: str @@ -301,9 +271,7 @@ class RetrievalService: def get_retrieval_service( - catalogue: CopernicusMarineCatalogue, - dataset_id: Optional[str], - dataset_url: Optional[str], + dataset_id: str, force_dataset_version_label: Optional[str], force_dataset_part_label: Optional[str], force_service_type_string: Optional[str], @@ -312,75 +280,27 @@ def get_retrieval_service( dataset_subset: Optional[DatasetTimeAndGeographicalSubset] = None, dataset_sync: bool = False, username: Optional[str] = None, + staging: bool = False, ) -> RetrievalService: + loop = asyncio.get_event_loop() + dataset_metadata = loop.run_until_complete( + get_dataset_metadata(dataset_id, staging=staging), + ) + # logger.debug(dataset_metadata) + if not dataset_metadata: + raise KeyError( + f"The requested dataset '{dataset_id}' was not found in the catalogue," + " you can use 'copernicusmarine describe --include-datasets " + "--contains ' to find datasets" + ) force_service_type: Optional[CopernicusMarineDatasetServiceType] = ( _service_type_from_string(force_service_type_string, command_type) if force_service_type_string else None ) - if dataset_id is None: - ( - dataset_id, - service_type, - suffix_path, - ) = parse_dataset_id_and_service_and_suffix_path_from_url( - catalogue, dataset_url - ) - force_service_type = ( - service_type if not force_service_type else force_service_type - ) - else: - if dataset_url is not None: - syntax_error = SyntaxError( - "Must specify only one of 'dataset_url' or 'dataset_id' options" - ) - raise syntax_error - suffix_path = "" - return _get_retrieval_service_from_dataset_id( - catalogue=catalogue, - dataset_id=dataset_id, - suffix_path=suffix_path, - force_dataset_version_label=force_dataset_version_label, - force_dataset_part_label=force_dataset_part_label, - force_service_type=force_service_type, - command_type=command_type, - index_parts=index_parts, - dataset_subset=dataset_subset, - dataset_sync=dataset_sync, - username=username, - ) - - -def _get_retrieval_service_from_dataset_id( - catalogue: CopernicusMarineCatalogue, - dataset_id: str, - suffix_path: str, - force_dataset_version_label: Optional[str], - force_dataset_part_label: Optional[str], - force_service_type: Optional[CopernicusMarineDatasetServiceType], - command_type: CommandType, - index_parts: bool, - dataset_subset: Optional[DatasetTimeAndGeographicalSubset], - dataset_sync: bool, - username: Optional[str], -) -> RetrievalService: - dataset: CopernicusMarineProductDataset = next_or_raise_exception( - ( - dataset - for product in catalogue.products - for dataset in product.datasets - if dataset_id == dataset.dataset_id - ), - KeyError( - f"The requested dataset '{dataset_id}' was not found in the catalogue," - " you can use 'copernicusmarine describe --include-datasets " - "--contains ' to find datasets" - ), - ) return _get_retrieval_service_from_dataset( - dataset=dataset, - suffix_path=suffix_path, + dataset=dataset_metadata, force_dataset_version_label=force_dataset_version_label, force_dataset_part_label=force_dataset_part_label, force_service_type=force_service_type, @@ -394,7 +314,6 @@ def _get_retrieval_service_from_dataset_id( def _get_retrieval_service_from_dataset( dataset: CopernicusMarineProductDataset, - suffix_path: str, force_dataset_version_label: Optional[str], force_dataset_part_label: Optional[str], force_service_type: Optional[CopernicusMarineDatasetServiceType], @@ -419,7 +338,6 @@ def _get_retrieval_service_from_dataset( dataset_id=dataset.dataset_id, dataset_version=dataset_version, force_dataset_part_label=force_dataset_part_label, - suffix_path=suffix_path, force_service_type=force_service_type, command_type=command_type, index_parts=index_parts, @@ -433,7 +351,6 @@ def _get_retrieval_service_from_dataset_version( dataset_id: str, dataset_version: CopernicusMarineDatasetVersion, force_dataset_part_label: Optional[str], - suffix_path: str, force_service_type: Optional[CopernicusMarineDatasetServiceType], command_type: CommandType, index_parts: bool, @@ -505,7 +422,7 @@ def _get_retrieval_service_from_dataset_version( return RetrievalService( dataset_id=dataset_id, service_type=service.service_type, - uri=service.uri + suffix_path, + uri=service.uri, dataset_valid_start_date=dataset_start_date, service_format=service.service_format, ) diff --git a/copernicusmarine/core_functions/subset.py b/copernicusmarine/core_functions/subset.py index 5a75ff32..172c547e 100644 --- a/copernicusmarine/core_functions/subset.py +++ b/copernicusmarine/core_functions/subset.py @@ -4,15 +4,13 @@ from datetime import datetime from typing import List, Optional -from copernicusmarine.catalogue_parser.catalogue_parser import ( +from copernicusmarine.catalogue_parser.models import ( CopernicusMarineDatasetServiceType, CopernicusMarineServiceFormat, - parse_catalogue, ) from copernicusmarine.catalogue_parser.request_structure import ( SubsetRequest, convert_motu_api_request_to_structure, - subset_request_from_file, ) from copernicusmarine.core_functions.credentials_utils import ( get_and_check_username_password, @@ -22,12 +20,9 @@ CommandType, RetrievalService, get_retrieval_service, - parse_dataset_id_and_service_and_suffix_path_from_url, ) from copernicusmarine.core_functions.utils import ( ServiceNotSupported, - create_cache_directory, - delete_cache_folder, get_unique_filename, ) from copernicusmarine.core_functions.versions_verifier import VersionVerifier @@ -43,7 +38,6 @@ def subset_function( - dataset_url: Optional[str], dataset_id: Optional[str], force_dataset_version: Optional[str], force_dataset_part: Optional[str], @@ -69,8 +63,6 @@ def subset_function( motu_api_request: Optional[str], force_download: bool, overwrite_output_data: bool, - overwrite_metadata_cache: bool, - no_metadata_cache: bool, disable_progress_bar: bool, staging: bool, netcdf_compression_enabled: bool, @@ -84,12 +76,6 @@ def subset_function( "Data will come from the staging environment." ) - if overwrite_metadata_cache: - delete_cache_folder() - - if not no_metadata_cache: - create_cache_directory() - if ( netcdf_compression_level is not None and netcdf_compression_enabled is False @@ -99,17 +85,15 @@ def subset_function( "--netcdf-compression-level option" ) - subset_request = SubsetRequest() + subset_request = SubsetRequest(dataset_id=dataset_id or "") if request_file: - subset_request = subset_request_from_file(request_file) + subset_request.from_file(request_file) if motu_api_request: motu_api_subset_request = convert_motu_api_request_to_structure( motu_api_request ) subset_request.update(motu_api_subset_request.__dict__) request_update_dict = { - "dataset_url": dataset_url, - "dataset_id": dataset_id, "force_dataset_version": force_dataset_version, "force_dataset_part": force_dataset_part, "variables": variables, @@ -132,11 +116,12 @@ def subset_function( "netcdf3_compatible": netcdf3_compatible, } subset_request.update(request_update_dict) + if not subset_request.dataset_id: + raise ValueError("Please provide a dataset id for a subset request.") username, password = get_and_check_username_password( username, password, credentials_file, - no_metadata_cache=no_metadata_cache, ) if all( e is None @@ -152,31 +137,9 @@ def subset_function( subset_request.end_datetime, ] ): - if not subset_request.dataset_id: - if subset_request.dataset_url: - catalogue = parse_catalogue( - no_metadata_cache=no_metadata_cache, - disable_progress_bar=disable_progress_bar, - staging=staging, - ) - ( - dataset_id, - _, - _, - ) = parse_dataset_id_and_service_and_suffix_path_from_url( - catalogue, subset_request.dataset_url - ) - else: - syntax_error = SyntaxError( - "Must specify at least one of " - "'dataset_url' or 'dataset_id' options" - ) - raise syntax_error - else: - dataset_id = subset_request.dataset_id logger.info( "To retrieve a complete dataset, please use instead: " - f"copernicusmarine get --dataset-id {dataset_id}" + f"copernicusmarine get --dataset-id {subset_request.dataset_id}" ) raise ValueError( "Missing subset option. Try 'copernicusmarine subset --help'." @@ -188,15 +151,8 @@ def subset_function( if overwrite_output_data: subset_request.overwrite_output_data = overwrite_output_data - catalogue = parse_catalogue( - no_metadata_cache=no_metadata_cache, - disable_progress_bar=disable_progress_bar, - staging=staging, - ) retrieval_service: RetrievalService = get_retrieval_service( - catalogue, subset_request.dataset_id, - subset_request.dataset_url, subset_request.force_dataset_version, subset_request.force_dataset_part, subset_request.force_service, @@ -263,8 +219,6 @@ def create_subset_template() -> None: "request_file": False, "motu_api_request": False, "overwrite_output_data": False, - "overwrite_metadata_cache": False, - "no_metadata_cache": False, }, output_file, indent=4, diff --git a/copernicusmarine/core_functions/utils.py b/copernicusmarine/core_functions/utils.py index 01d2ec36..564df704 100644 --- a/copernicusmarine/core_functions/utils.py +++ b/copernicusmarine/core_functions/utils.py @@ -1,6 +1,5 @@ import asyncio import logging -import os import pathlib import re from datetime import datetime @@ -26,9 +25,6 @@ from requests import PreparedRequest from copernicusmarine import __version__ as copernicusmarine_version -from copernicusmarine.core_functions.environment_variables import ( - COPERNICUSMARINE_CACHE_DIRECTORY, -) logger = logging.getLogger("copernicus_marine_root_logger") @@ -41,14 +37,6 @@ FORCE_DOWNLOAD_CLI_PROMPT_MESSAGE = "Do you want to proceed with download?" -USER_DEFINED_CACHE_DIRECTORY: str = COPERNICUSMARINE_CACHE_DIRECTORY -DEFAULT_CLIENT_BASE_DIRECTORY: pathlib.Path = ( - pathlib.Path(USER_DEFINED_CACHE_DIRECTORY) - if USER_DEFINED_CACHE_DIRECTORY - else pathlib.Path.home() -) / ".copernicusmarine" - -CACHE_BASE_DIRECTORY: pathlib.Path = DEFAULT_CLIENT_BASE_DIRECTORY / "cache" DATETIME_SUPPORTED_FORMATS = [ "%Y", @@ -160,23 +148,6 @@ def add_copernicusmarine_version_in_dataset_attributes( return dataset -def create_cache_directory(): - pathlib.Path(CACHE_BASE_DIRECTORY).mkdir(parents=True, exist_ok=True) - - -def delete_cache_folder(quiet: bool = False): - try: - elements = pathlib.Path(CACHE_BASE_DIRECTORY).glob("*") - files = [x for x in elements if x.is_file()] - for file in files: - os.remove(file) - if not quiet: - logger.info("Old cache successfully deleted") - except Exception as exc: - logger.warning("Error occurred while deleting old cache files") - raise exc - - async def rolling_batch_gather( promises: Union[List[Coroutine[Any, Any, Any]], List[Awaitable[Any]]], per_batch: int, diff --git a/copernicusmarine/download_functions/subset_xarray.py b/copernicusmarine/download_functions/subset_xarray.py index 1de5e419..0d080bdd 100644 --- a/copernicusmarine/download_functions/subset_xarray.py +++ b/copernicusmarine/download_functions/subset_xarray.py @@ -8,7 +8,7 @@ import xarray from pandas import Timestamp -from copernicusmarine.catalogue_parser.catalogue_parser import ( +from copernicusmarine.catalogue_parser.models import ( CopernicusMarineDatasetServiceType, ) from copernicusmarine.catalogue_parser.request_structure import ( diff --git a/copernicusmarine/python_interface/describe.py b/copernicusmarine/python_interface/describe.py index efd2a354..c7a179a4 100644 --- a/copernicusmarine/python_interface/describe.py +++ b/copernicusmarine/python_interface/describe.py @@ -20,8 +20,6 @@ def describe( include_versions: bool = False, include_all: bool = False, contains: list[str] = [], - overwrite_metadata_cache: bool = False, - no_metadata_cache: bool = False, disable_progress_bar: bool = False, staging: bool = False, ) -> dict[str, Any]: @@ -38,8 +36,6 @@ def describe( include_versions (bool, optional): Whether to include all versions of each dataset. Defaults to False. include_all (bool, optional): Whether to include all metadata information. Defaults to False. contains (list[str], optional): List of strings to filter items containing these values. Defaults to []. - overwrite_metadata_cache (bool, optional): Whether to overwrite the metadata cache. Defaults to False. - no_metadata_cache (bool, optional): Whether to skip using the metadata cache. Defaults to False. Returns: dict[str, Any]: A dictionary containing the retrieved metadata information. @@ -60,8 +56,6 @@ def describe( include_keywords, include_versions, contains, - overwrite_metadata_cache, - no_metadata_cache, disable_progress_bar, staging=staging, ) diff --git a/copernicusmarine/python_interface/get.py b/copernicusmarine/python_interface/get.py index 93c9d28a..3eb25ec0 100644 --- a/copernicusmarine/python_interface/get.py +++ b/copernicusmarine/python_interface/get.py @@ -18,8 +18,7 @@ @deprecated_python_option(**DEPRECATED_OPTIONS.dict_old_names_to_new_names) @log_exception_and_exit def get( - dataset_url: Optional[str] = None, - dataset_id: Optional[str] = None, + dataset_id: Optional[str], dataset_version: Optional[str] = None, dataset_part: Optional[str] = None, username: Optional[str] = None, @@ -32,8 +31,6 @@ def get( overwrite_output_data: bool = False, request_file: Optional[Union[pathlib.Path, str]] = None, service: Optional[str] = None, - overwrite_metadata_cache: bool = False, - no_metadata_cache: bool = False, filter: Optional[str] = None, regex: Optional[str] = None, file_list: Optional[Union[pathlib.Path, str]] = None, @@ -49,7 +46,6 @@ def get( Fetches data from the Copernicus Marine server based on the provided parameters. Args: - dataset_url (str, optional): The URL of the dataset to retrieve. dataset_id (str, optional): The unique identifier of the dataset. dataset_version (str, optional): Force the use of a specific dataset version. dataset_part (str, optional): Force the use of a specific dataset part. @@ -61,8 +57,6 @@ def get( overwrite_output_data (bool, optional): If True, overwrite existing output files. request_file (Union[pathlib.Path, str], optional): Path to a file containing request parameters. For more information please refer to the README. service (str, optional): Force the use of a specific service. - overwrite_metadata_cache (bool, optional): If True, overwrite the metadata cache. - no_metadata_cache (bool, optional): If True, do not use the metadata cache. no_directories (bool, optional): If True, downloaded files will not be organized into directories. show_outputnames (bool, optional): If True, display the names of the downloaded files. filter (str, optional): Apply a filter to the downloaded data. @@ -91,7 +85,6 @@ def get( elif download_file_list: log_deprecated_message("download_file_list", "create_file_list") return get_function( - dataset_url=dataset_url, dataset_id=dataset_id, force_dataset_version=dataset_version, force_dataset_part=dataset_part, @@ -105,8 +98,6 @@ def get( overwrite_output_data=overwrite_output_data, request_file=request_file, force_service=service, - overwrite_metadata_cache=overwrite_metadata_cache, - no_metadata_cache=no_metadata_cache, filter=filter, regex=regex, file_list_path=file_list, diff --git a/copernicusmarine/python_interface/load_utils.py b/copernicusmarine/python_interface/load_utils.py index dc742b7a..7530d9a3 100644 --- a/copernicusmarine/python_interface/load_utils.py +++ b/copernicusmarine/python_interface/load_utils.py @@ -3,9 +3,8 @@ import pandas import xarray -from copernicusmarine.catalogue_parser.catalogue_parser import ( +from copernicusmarine.catalogue_parser.models import ( CopernicusMarineDatasetServiceType, - parse_catalogue, ) from copernicusmarine.catalogue_parser.request_structure import LoadRequest from copernicusmarine.core_functions.credentials_utils import ( @@ -16,10 +15,7 @@ RetrievalService, get_retrieval_service, ) -from copernicusmarine.core_functions.utils import ( - ServiceNotSupported, - delete_cache_folder, -) +from copernicusmarine.core_functions.utils import ServiceNotSupported from copernicusmarine.download_functions.subset_xarray import ( check_dataset_subset_bounds, date_to_datetime, @@ -28,20 +24,10 @@ def load_data_object_from_load_request( load_request: LoadRequest, - disable_progress_bar: bool, arco_series_load_function: Callable, ) -> Union[xarray.Dataset, pandas.DataFrame]: - if load_request.overwrite_metadata_cache: - delete_cache_folder() - - catalogue = parse_catalogue( - no_metadata_cache=load_request.no_metadata_cache, - disable_progress_bar=disable_progress_bar, - ) retrieval_service: RetrievalService = get_retrieval_service( - catalogue=catalogue, dataset_id=load_request.dataset_id, - dataset_url=load_request.dataset_url, force_dataset_version_label=load_request.force_dataset_version, force_dataset_part_label=load_request.force_dataset_part, force_service_type_string=load_request.force_service, diff --git a/copernicusmarine/python_interface/login.py b/copernicusmarine/python_interface/login.py index a193ebfc..d3ee2eb5 100644 --- a/copernicusmarine/python_interface/login.py +++ b/copernicusmarine/python_interface/login.py @@ -1,8 +1,10 @@ import pathlib from typing import Optional +from copernicusmarine.core_functions.credentials_utils import ( + DEFAULT_CLIENT_BASE_DIRECTORY, +) from copernicusmarine.core_functions.login import login_function -from copernicusmarine.core_functions.utils import DEFAULT_CLIENT_BASE_DIRECTORY def login( diff --git a/copernicusmarine/python_interface/open_dataset.py b/copernicusmarine/python_interface/open_dataset.py index 96d44503..e063848a 100644 --- a/copernicusmarine/python_interface/open_dataset.py +++ b/copernicusmarine/python_interface/open_dataset.py @@ -47,8 +47,7 @@ def load_xarray_dataset(*args, **kwargs): @deprecated_python_option(**DEPRECATED_OPTIONS.dict_old_names_to_new_names) @log_exception_and_exit def open_dataset( - dataset_url: Optional[str] = None, - dataset_id: Optional[str] = None, + dataset_id: str, dataset_version: Optional[str] = None, dataset_part: Optional[str] = None, username: Optional[str] = None, @@ -66,9 +65,6 @@ def open_dataset( subset_method: SubsetMethod = DEFAULT_SUBSET_METHOD, service: Optional[str] = None, credentials_file: Optional[Union[pathlib.Path, str]] = None, - overwrite_metadata_cache: bool = False, - no_metadata_cache: bool = False, - disable_progress_bar: bool = False, ) -> xarray.Dataset: """ Load an xarray dataset using "lazy-loading" mode from a Copernicus Marine data source using either the ARCO series protocol. @@ -76,8 +72,7 @@ def open_dataset( It supports various parameters for customization, such as specifying ge ographical bounds, temporal range, depth range, and more. Args: - dataset_url (str, optional): The URL of the dataset. Either `dataset_url` or `dataset_id` should be provided. - dataset_id (str, optional): The ID of the dataset. Either `dataset_url` or `dataset_id` should be provided. + dataset_id (str, optional): The ID of the dataset. `dataset_id` is mandatory. dataset_version (str, optional): Force the use of a specific dataset version. dataset_part (str, optional): Force the use of a specific dataset part. username (str, optional): Username for authentication, if required. @@ -95,8 +90,6 @@ def open_dataset( end_datetime (datetime, optional): The end datetime for temporal subsetting. service (str, optional): Force the use of a specific service (ARCO geo series or time series). credentials_file (Union[pathlib.Path, str], optional): Path to a file containing authentication credentials. - overwrite_metadata_cache (bool, optional): If True, overwrite the metadata cache. - no_metadata_cache (bool, optional): If True, do not use the metadata cache. Returns: xarray.Dataset: The loaded xarray dataset. @@ -107,7 +100,6 @@ def open_dataset( pathlib.Path(credentials_file) if credentials_file else None ) load_request = LoadRequest( - dataset_url=dataset_url, dataset_id=dataset_id, force_dataset_version=dataset_version, force_dataset_part=dataset_part, @@ -136,12 +128,9 @@ def open_dataset( subset_method=subset_method, force_service=service, credentials_file=credentials_file, - overwrite_metadata_cache=overwrite_metadata_cache, - no_metadata_cache=no_metadata_cache, ) dataset = load_data_object_from_load_request( load_request, - disable_progress_bar, open_dataset_from_arco_series, ) return dataset diff --git a/copernicusmarine/python_interface/read_dataframe.py b/copernicusmarine/python_interface/read_dataframe.py index acd332ab..97f371f2 100644 --- a/copernicusmarine/python_interface/read_dataframe.py +++ b/copernicusmarine/python_interface/read_dataframe.py @@ -47,8 +47,7 @@ def load_pandas_dataframe(*args, **kwargs): @deprecated_python_option(**DEPRECATED_OPTIONS.dict_old_names_to_new_names) @log_exception_and_exit def read_dataframe( - dataset_url: Optional[str] = None, - dataset_id: Optional[str] = None, + dataset_id: str, dataset_version: Optional[str] = None, dataset_part: Optional[str] = None, username: Optional[str] = None, @@ -66,16 +65,12 @@ def read_dataframe( subset_method: SubsetMethod = DEFAULT_SUBSET_METHOD, force_service: Optional[str] = None, credentials_file: Optional[Union[pathlib.Path, str]] = None, - overwrite_metadata_cache: bool = False, - no_metadata_cache: bool = False, - disable_progress_bar: bool = False, ) -> pandas.DataFrame: """ Immediately loads a Pandas DataFrame into memory from a specified dataset. Unlike “lazy-loading”, the data is loaded as soon as this function is executed, which may be preferable when rapid access to the entire data set is required, but may require careful memory management. Args: - dataset_url (str, optional): The URL of the dataset. dataset_id (str, optional): The identifier of the dataset. dataset_version (str, optional): Force a specific dataset version. dataset_part (str, optional): Force a specific dataset part. @@ -94,8 +89,6 @@ def read_dataframe( subset_method (str, optional): The subset method ('nearest' or 'strict') when requesting the dataset. If strict, you can only request dimension strictly inside the dataset. force_service (str, optional): Force a specific service for data download. credentials_file (Union[pathlib.Path, str], optional): Path to a credentials file for authentication. - overwrite_metadata_cache (bool, optional): If True, overwrite the metadata cache. - no_metadata_cache (bool, optional): If True, do not use metadata caching. Returns: pandas.DataFrame: A DataFrame containing the loaded Copernicus Marine data. @@ -106,7 +99,6 @@ def read_dataframe( pathlib.Path(credentials_file) if credentials_file else None ) load_request = LoadRequest( - dataset_url=dataset_url, dataset_id=dataset_id, force_dataset_version=dataset_version, force_dataset_part=dataset_part, @@ -135,12 +127,9 @@ def read_dataframe( ), force_service=force_service, credentials_file=credentials_file, - overwrite_metadata_cache=overwrite_metadata_cache, - no_metadata_cache=no_metadata_cache, ) dataset = load_data_object_from_load_request( load_request, - disable_progress_bar, read_dataframe_from_arco_series, ) return dataset diff --git a/copernicusmarine/python_interface/subset.py b/copernicusmarine/python_interface/subset.py index dcc70411..38fe81b8 100644 --- a/copernicusmarine/python_interface/subset.py +++ b/copernicusmarine/python_interface/subset.py @@ -22,8 +22,7 @@ @deprecated_python_option(**DEPRECATED_OPTIONS.dict_old_names_to_new_names) @log_exception_and_exit def subset( - dataset_url: Optional[str] = None, - dataset_id: Optional[str] = None, + dataset_id: Optional[str], dataset_version: Optional[str] = None, dataset_part: Optional[str] = None, username: Optional[str] = None, @@ -48,8 +47,6 @@ def subset( motu_api_request: Optional[str] = None, force_download: bool = False, overwrite_output_data: bool = False, - overwrite_metadata_cache: bool = False, - no_metadata_cache: bool = False, disable_progress_bar: bool = False, staging: bool = False, netcdf_compression_enabled: bool = False, @@ -60,7 +57,6 @@ def subset( Extracts a subset of data from a specified dataset using given parameters. Args: - dataset_url (str, optional): The URL of the dataset to retrieve. dataset_id (str, optional): The unique identifier of the dataset. dataset_version (str, optional): Force the use of a specific dataset version. dataset_part (str, optional): Force the use of a specific dataset part. @@ -72,8 +68,6 @@ def subset( overwrite_output_data (bool, optional): If True, overwrite existing output files. request_file (Union[pathlib.Path, str], optional): Path to a file containing request parameters. For more information please refer to the README. service (str, optional): Force the use of a specific service. - overwrite_metadata_cache (bool, optional): If True, overwrite the metadata cache. - no_metadata_cache (bool, optional): If True, do not use the metadata cache. variables (List[str], optional): List of variable names to extract. minimum_longitude (float, optional): Minimum longitude value for spatial subset. maximum_longitude (float, optional): Maximum longitude value for spatial subset. @@ -106,7 +100,6 @@ def subset( end_datetime = homogenize_datetime(end_datetime) return subset_function( - dataset_url, dataset_id, dataset_version, dataset_part, @@ -132,8 +125,6 @@ def subset( motu_api_request, force_download, overwrite_output_data, - overwrite_metadata_cache, - no_metadata_cache, disable_progress_bar, staging=staging, netcdf_compression_enabled=netcdf_compression_enabled, diff --git a/poetry.lock b/poetry.lock index da7370c1..5a4116dd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -170,17 +170,17 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p [[package]] name = "boto3" -version = "1.34.139" +version = "1.34.143" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.139-py3-none-any.whl", hash = "sha256:98b2a12bcb30e679fa9f60fc74145a39db5ec2ca7b7c763f42896e3bd9b3a38d"}, - {file = "boto3-1.34.139.tar.gz", hash = "sha256:32b99f0d76ec81fdca287ace2c9744a2eb8b92cb62bf4d26d52a4f516b63a6bf"}, + {file = "boto3-1.34.143-py3-none-any.whl", hash = "sha256:0d16832f23e6bd3ae94e35ea8e625529850bfad9baccd426de96ad8f445d8e03"}, + {file = "boto3-1.34.143.tar.gz", hash = "sha256:b590ce80c65149194def43ebf0ea1cf0533945502507837389a8d22e3ecbcf05"}, ] [package.dependencies] -botocore = ">=1.34.139,<1.35.0" +botocore = ">=1.34.143,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -189,13 +189,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.139" +version = "1.34.143" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.139-py3-none-any.whl", hash = "sha256:dd1e085d4caa2a4c1b7d83e3bc51416111c8238a35d498e9d3b04f3b63b086ba"}, - {file = "botocore-1.34.139.tar.gz", hash = "sha256:df023d8cf8999d574214dad4645cb90f9d2ccd1494f6ee2b57b1ab7522f6be77"}, + {file = "botocore-1.34.143-py3-none-any.whl", hash = "sha256:094aea179e8aaa1bc957ad49cc27d93b189dd3a1f3075d8b0ca7c445a2a88430"}, + {file = "botocore-1.34.143.tar.gz", hash = "sha256:059f032ec05733a836e04e869c5a15534420102f93116f3bc9a5b759b0651caf"}, ] [package.dependencies] @@ -209,31 +209,15 @@ urllib3 = [ [package.extras] crt = ["awscrt (==0.20.11)"] -[[package]] -name = "cachier" -version = "3.0.0" -description = "Persistent, stale-free, local and cross-machine caching for Python functions." -optional = false -python-versions = "*" -files = [ - {file = "cachier-3.0.0-py3-none-any.whl", hash = "sha256:627455077d3619a27b1c63368d49533ffe6807a1b19fe6944e4c8f3ac895d1bc"}, - {file = "cachier-3.0.0.tar.gz", hash = "sha256:f756ebeabf8b397f75fbbb9a5841972d4c85a81b7313e2812b3448e80d74c66d"}, -] - -[package.dependencies] -portalocker = ">=2.3.2" -setuptools = ">=67.6.0" -watchdog = ">=2.3.1" - [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -249,32 +233,41 @@ files = [ [[package]] name = "cftime" -version = "1.6.3" +version = "1.6.4" description = "Time-handling functionality from netcdf4-python" optional = false python-versions = ">=3.8" files = [ - {file = "cftime-1.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b62d42546fa5c914dfea5b15a9aaed2087ea1211cc36d08c374502ef95892038"}, - {file = "cftime-1.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb6dd70b2ccabfe1a14b7fbb0bbdce0418e71697094373c0d573c880790fa291"}, - {file = "cftime-1.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9878bfd8c1c3f24184ecbd528f739ba46ebaceaf1c8a24d348d7befb117a285"}, - {file = "cftime-1.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:3cf6e216a4c06f9a628cdf8e9c9d5e8097fb3eb02dd087dd14ab3b18478a7271"}, - {file = "cftime-1.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d2c01456d9d7b46aa710a41d1c711a50d5ea259aff4a987d0e973d1093bc922"}, - {file = "cftime-1.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:80eb1170ce1639016f55760847f4aadd04b0312496c5bac2797e930914bba48d"}, - {file = "cftime-1.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d87dadd0824262bdd7493babd2a44447da0a22175ded8ae9e060a3aebec7c5d7"}, - {file = "cftime-1.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:0a38eb9f5c733a23e1714bd3ef2762ed5acee34f127670f8fb4ad6464946f6b3"}, - {file = "cftime-1.6.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2d113a01ab924445e61d65c26bbd95bc08e4a22878d3b947064bba056c884c4a"}, - {file = "cftime-1.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f11685663a6af97418908060492a07663c16d42519c139ca03c2ffb1377fd25"}, - {file = "cftime-1.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a98abb1d46d118e52b0611ce668a0b714b407be26177ef0581ecf5e95f894725"}, - {file = "cftime-1.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:4d6fbd5f41b322cfa7b0ac3aaadeceb4450100a164b5bccbbb9e7c5048489a88"}, - {file = "cftime-1.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bedb577bc8b8f3f10f5336c0792e5dae88605781890f50f36b45bb46907968e8"}, - {file = "cftime-1.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:022dabf1610cdd04a693e730fa8f71d307059717f29dba921e7486e553412bb4"}, - {file = "cftime-1.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbf782ab4ac0605bdec2b941952c897595613203942b7f8c2fccd17efa5147df"}, - {file = "cftime-1.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:9eb177a02db7cd84aa6962278e4bd2d3106a545de82e6aacd9404f1e153661db"}, - {file = "cftime-1.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b86be8c2f254147be4ba88f12099466dde457a4a3a21de6c69d52a7224c13ae"}, - {file = "cftime-1.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:523b9a6bf03f5e36407979e248381d0fcab2d225b915bbde77d00c6dde192b90"}, - {file = "cftime-1.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a14d2c7d22fd2a6dfa6ad563283b6d6679f1df95e0ed8d14b8f284dad402887"}, - {file = "cftime-1.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:d9b00c2844c7a1701d8ede5336b6321dfee256ceab81a34a1aff0483d56891a6"}, - {file = "cftime-1.6.3.tar.gz", hash = "sha256:d0a6b29f72a13f08e008b9becff247cc75c84acb213332ede18879c5b6aa4dfd"}, + {file = "cftime-1.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ee70074df4bae0d9ee98f201cf5f11fd302791cf1cdeb73c34f685d6b632e17d"}, + {file = "cftime-1.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e5456fd58d4cc6b8d7b4932b749617ee142b62a52bc5d8e3c282ce69ce3a20ba"}, + {file = "cftime-1.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1289e08617be350a6b26c6e4352a0cb088625ac33d25e95110df549c26d6ab8e"}, + {file = "cftime-1.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b132d9225b4a109929866200846c72302316db9069e2de3ec8d8ec377f567f"}, + {file = "cftime-1.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ca1a264570e68fbb611bba251641b8efd0cf88c0ad2dcab5fa784df264232b75"}, + {file = "cftime-1.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:6fc82928cbf477bebf233f41914e64bff7b9e894c7f0c34170784a48250f8da7"}, + {file = "cftime-1.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c1558d9b477bd29626cd8bfc89e736635f72887d1a993e2834ab579bba7abb8c"}, + {file = "cftime-1.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:03494e7b66a2fbb6b04e364ab67185130dee0ced660abac5c1559070571d143d"}, + {file = "cftime-1.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dcb2a01d4e614437582af33b36db4fb441b7666758482864827a1f037d2b639"}, + {file = "cftime-1.6.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b47bf25195fb3889bbae34df0e80957eb69c48f66902f5d538c7a8ec34253f6"}, + {file = "cftime-1.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d4f2cc0d5c6ffba9c5b0fd1ecd0c7c1c426d0be7b8de1480e2a9fb857c1905e9"}, + {file = "cftime-1.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:76b8f1e5d1e424accdf760a43e0a1793a7b640bab83cb067273d5c9dbb336c44"}, + {file = "cftime-1.6.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c349a91fa7ac9ec50118b04a8746bdea967bd2fc525d87c776003040b8d3392"}, + {file = "cftime-1.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:588d073400798adc24ece759cd1cb24ef730f55d1f70e31a898e7686f9d763d8"}, + {file = "cftime-1.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e07b91b488570573bbeb6f815656a8974d13d15b2279c82de2927f4f692bbcd"}, + {file = "cftime-1.6.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f92f2e405eeda47b30ab6231d8b7d136a55f21034d394f93ade322d356948654"}, + {file = "cftime-1.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:567574df94d0de1101bb5da76e7fbc6eabfddeeb2eb8cf83286b3599a136bbf7"}, + {file = "cftime-1.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:5b5ad7559a16bedadb66af8e417b6805f758acb57aa38d2730844dfc63a1e667"}, + {file = "cftime-1.6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c072fe9e09925af66a9473edf5752ca1890ba752e7c1935d1f0245ad48f0977c"}, + {file = "cftime-1.6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c05a71389f53d6340cb365b60f028c08268c72401660b9ef76108dee9f1cb5b2"}, + {file = "cftime-1.6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0edeb1cb019d8155b2513cffb96749c0d7d459370e69bdf03077e0bee214aed8"}, + {file = "cftime-1.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f05d5d6bb4137f9783fa61ad330030fcea8dcc6946dea69a27774edbe480e7"}, + {file = "cftime-1.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:b32ac1278a2a111b066d5a1e6e5ce6f38c4c505993a6a3130873b56f99d7b56f"}, + {file = "cftime-1.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c20f03e12af39534c3450bba376272803bfb850b5ce6433c839bfaa99f8d835a"}, + {file = "cftime-1.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:90609b3c1a31a756a68ecdbc961a4ce0b22c1620f166c8dabfa3a4c337ac8b9e"}, + {file = "cftime-1.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbe11ad73b2a0ddc79995da21459fc2a3fd6b1593ca73f00a60e4d81c3e230f3"}, + {file = "cftime-1.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25f043703e785de0bd7cd8222c0a53317e9aeb3dfc062588b05e6f3ebb007468"}, + {file = "cftime-1.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f9acc272df1022f24fe7dbe9de43fa5d8271985161df14549e4d8d28c90dc9ea"}, + {file = "cftime-1.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:e8467b6fbf8dbfe0be8c04d61180765fdd3b9ab0fe51313a0bbf87e63634a3d8"}, + {file = "cftime-1.6.4.tar.gz", hash = "sha256:e325406193758a7ed67308deb52e727782a19e384e183378e7ff62098be0aedc"}, ] [package.dependencies] @@ -420,13 +413,13 @@ files = [ [[package]] name = "dask" -version = "2024.4.2" +version = "2024.7.0" description = "Parallel PyData with Task Scheduling" optional = false python-versions = ">=3.9" files = [ - {file = "dask-2024.4.2-py3-none-any.whl", hash = "sha256:56fbe92472e3b323ab7beaf2dc8437d48066ac21aa9c2c17ac40d2b6f7b4c414"}, - {file = "dask-2024.4.2.tar.gz", hash = "sha256:3d7a516468d96e72581b84c7bb00172366f30d24c689ea4e9bd1334ab6d98f8a"}, + {file = "dask-2024.7.0-py3-none-any.whl", hash = "sha256:0f30f218a1fe1c8e9a6ba8add1207088ba9ff049098d4ea4ce045fd5ff7ca914"}, + {file = "dask-2024.7.0.tar.gz", hash = "sha256:0060bae9a58b5b3ce7e0d97040e903b4d3db09ba49222101cfc40f9834a8a6bc"}, ] [package.dependencies] @@ -435,16 +428,16 @@ cloudpickle = ">=1.5.0" fsspec = ">=2021.09.0" importlib-metadata = {version = ">=4.13.0", markers = "python_version < \"3.12\""} packaging = ">=20.0" -partd = ">=1.2.0" +partd = ">=1.4.0" pyyaml = ">=5.3.1" toolz = ">=0.10.0" [package.extras] array = ["numpy (>=1.21)"] complete = ["dask[array,dataframe,diagnostics,distributed]", "lz4 (>=4.3.2)", "pyarrow (>=7.0)", "pyarrow-hotfix"] -dataframe = ["dask-expr (>=1.0,<1.1)", "dask[array]", "pandas (>=1.3)"] +dataframe = ["dask-expr (>=1.1,<1.2)", "dask[array]", "pandas (>=2.0)"] diagnostics = ["bokeh (>=2.4.2)", "jinja2 (>=2.10.3)"] -distributed = ["distributed (==2024.4.2)"] +distributed = ["distributed (==2024.7.0)"] test = ["pandas[test]", "pre-commit", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-timeout", "pytest-xdist"] [[package]] @@ -510,18 +503,18 @@ files = [ [[package]] name = "filelock" -version = "3.13.4" +version = "3.15.4" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.4-py3-none-any.whl", hash = "sha256:404e5e9253aa60ad457cae1be07c0f0ca90a63931200a47d9b6a6af84fd7b45f"}, - {file = "filelock-3.13.4.tar.gz", hash = "sha256:d13f466618bfde72bd2c18255e269f72542c6e70e7bac83a0232d6b1cc5c8cf4"}, + {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, + {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] @@ -612,13 +605,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.3.1" +version = "2024.6.1" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.3.1-py3-none-any.whl", hash = "sha256:918d18d41bf73f0e2b261824baeb1b124bcf771767e3a26425cd7dec3332f512"}, - {file = "fsspec-2024.3.1.tar.gz", hash = "sha256:f39780e282d7d117ffb42bb96992f8a90795e4d0fb0f661a70ca39fe9c43ded9"}, + {file = "fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e"}, + {file = "fsspec-2024.6.1.tar.gz", hash = "sha256:fad7d7e209dd4c1208e3bbfda706620e0da5142bebbd9c384afb95b07e798e49"}, ] [package.extras] @@ -626,7 +619,8 @@ abfs = ["adlfs"] adl = ["adlfs"] arrow = ["pyarrow (>=1)"] dask = ["dask", "distributed"] -devel = ["pytest", "pytest-cov"] +dev = ["pre-commit", "ruff"] +doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] dropbox = ["dropbox", "dropboxdrivefs", "requests"] full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] fuse = ["fusepy"] @@ -643,17 +637,20 @@ s3 = ["s3fs"] sftp = ["paramiko"] smb = ["smbprotocol"] ssh = ["paramiko"] +test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] +test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] +test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] tqdm = ["tqdm"] [[package]] name = "identify" -version = "2.5.36" +version = "2.6.0" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, - {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, + {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, + {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, ] [package.extras] @@ -672,22 +669,22 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.1.0" +version = "8.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, - {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "ipython" @@ -769,165 +766,153 @@ files = [ [[package]] name = "lxml" -version = "5.2.1" +version = "5.2.2" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1"}, - {file = "lxml-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a"}, - {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01"}, - {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1"}, - {file = "lxml-5.2.1-cp310-cp310-win32.whl", hash = "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5"}, - {file = "lxml-5.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f"}, - {file = "lxml-5.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867"}, - {file = "lxml-5.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a"}, - {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f"}, - {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534"}, - {file = "lxml-5.2.1-cp311-cp311-win32.whl", hash = "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be"}, - {file = "lxml-5.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102"}, - {file = "lxml-5.2.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851"}, - {file = "lxml-5.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0"}, - {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169"}, - {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4"}, - {file = "lxml-5.2.1-cp312-cp312-win32.whl", hash = "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134"}, - {file = "lxml-5.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a"}, - {file = "lxml-5.2.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c"}, - {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0"}, - {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1"}, - {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863"}, - {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62"}, - {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461"}, - {file = "lxml-5.2.1-cp36-cp36m-win32.whl", hash = "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0"}, - {file = "lxml-5.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289"}, - {file = "lxml-5.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029"}, - {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af"}, - {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0"}, - {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75"}, - {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8"}, - {file = "lxml-5.2.1-cp37-cp37m-win32.whl", hash = "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd"}, - {file = "lxml-5.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c"}, - {file = "lxml-5.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b"}, - {file = "lxml-5.2.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a"}, - {file = "lxml-5.2.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585"}, - {file = "lxml-5.2.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86"}, - {file = "lxml-5.2.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533"}, - {file = "lxml-5.2.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c"}, - {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637"}, - {file = "lxml-5.2.1-cp38-cp38-win32.whl", hash = "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da"}, - {file = "lxml-5.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806"}, - {file = "lxml-5.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd"}, - {file = "lxml-5.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b"}, - {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c"}, - {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188"}, - {file = "lxml-5.2.1-cp39-cp39-win32.whl", hash = "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708"}, - {file = "lxml-5.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95"}, - {file = "lxml-5.2.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11"}, - {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1"}, - {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94"}, - {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98"}, - {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e"}, - {file = "lxml-5.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66"}, - {file = "lxml-5.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c"}, - {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa"}, - {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817"}, - {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460"}, - {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96"}, - {file = "lxml-5.2.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860"}, - {file = "lxml-5.2.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d"}, - {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f"}, - {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138"}, - {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b"}, - {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85"}, - {file = "lxml-5.2.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144"}, - {file = "lxml-5.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc"}, - {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354"}, - {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9"}, - {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5"}, - {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246"}, - {file = "lxml-5.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704"}, - {file = "lxml-5.2.1.tar.gz", hash = "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306"}, + {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632"}, + {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526"}, + {file = "lxml-5.2.2-cp310-cp310-win32.whl", hash = "sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30"}, + {file = "lxml-5.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7"}, + {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545"}, + {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b"}, + {file = "lxml-5.2.2-cp311-cp311-win32.whl", hash = "sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438"}, + {file = "lxml-5.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be"}, + {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391"}, + {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836"}, + {file = "lxml-5.2.2-cp312-cp312-win32.whl", hash = "sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a"}, + {file = "lxml-5.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48"}, + {file = "lxml-5.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56"}, + {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9"}, + {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264"}, + {file = "lxml-5.2.2-cp36-cp36m-win32.whl", hash = "sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3"}, + {file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"}, + {file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"}, + {file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"}, + {file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"}, + {file = "lxml-5.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1"}, + {file = "lxml-5.2.2-cp38-cp38-win32.whl", hash = "sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30"}, + {file = "lxml-5.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6"}, + {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30"}, + {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9"}, + {file = "lxml-5.2.2-cp39-cp39-win32.whl", hash = "sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf"}, + {file = "lxml-5.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324"}, + {file = "lxml-5.2.2.tar.gz", hash = "sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87"}, ] [package.extras] @@ -1063,38 +1048,36 @@ files = [ [[package]] name = "netcdf4" -version = "1.6.5" +version = "1.7.1.post1" description = "Provides an object-oriented python interface to the netCDF version 4 library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "netCDF4-1.6.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d23b97cbde2bf413fadc4697c5c255a0436511c02f811e127e0fb12f5b882a4c"}, - {file = "netCDF4-1.6.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e5edfed673005f47f8d2fbea9c72c382b085dd358ac3c20ca743a563ed7b90e"}, - {file = "netCDF4-1.6.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10d2ac9ae1308ca837d86c6dc304ec455a85bdba0f2175e222844a54589168dc"}, - {file = "netCDF4-1.6.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a63a2be2f80977ac23bb0aa736c565011fd4639097ce0922e01b0dc38015df2"}, - {file = "netCDF4-1.6.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aaceea2097d292bad398d9f9b4fe403efa7b1568fcfa6faba9b67b1630027f9"}, - {file = "netCDF4-1.6.5-cp310-cp310-win_amd64.whl", hash = "sha256:111357d9e12eb79e8d58bfd91bc6b230d35b17a0ebd8c546d17416e8ceebea49"}, - {file = "netCDF4-1.6.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c5fede0b34c0a02a1b9e84116bfb3fcd2f80124a651d4836e72b785d10e2f15"}, - {file = "netCDF4-1.6.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3de5512b9270aa6472e4f3aa2bf895a7364c1d4f8667ce3b82e8232197d4fec8"}, - {file = "netCDF4-1.6.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b20971a164431f6eca1d24df8aa153db15c2c1b9630e83ccc5cf004e8ac8151d"}, - {file = "netCDF4-1.6.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad1101d538077152b866782e44458356981526bf2ea9cc07930bf28b589c82a7"}, - {file = "netCDF4-1.6.5-cp311-cp311-win_amd64.whl", hash = "sha256:de4dc973fae9e2bbdf42e094125e423a4c25393172a61958314969b055a38889"}, - {file = "netCDF4-1.6.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:19e16c63cdd7c0dbffe284a4a65f226ba1026f476f35cbedd099b4792b395f69"}, - {file = "netCDF4-1.6.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b994afce2ca4073f6b757385a6c0ffec25ecaae2b8821535b303c7cdbf6de42b"}, - {file = "netCDF4-1.6.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0187646e3348e7a8cd654617dda65517df138042c94c2fcc6682ff7c8c6654dc"}, - {file = "netCDF4-1.6.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1ab5dabac27d25fcc82c52dc29a74a6585e865208cce35f4e285df83d3df0b2"}, - {file = "netCDF4-1.6.5-cp312-cp312-win_amd64.whl", hash = "sha256:081e9043ac6160989f60570928eabe803c88ce7df1d3f79f2345dc48f68ef752"}, - {file = "netCDF4-1.6.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b47b22dda5b25ba6291f97634d7ac67b0a843f8ae5c9d9d5813c15364f66d0a"}, - {file = "netCDF4-1.6.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4609dd62d14798c9524327287091875449d68588c128abb768fc0c76c4a28165"}, - {file = "netCDF4-1.6.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2455e9d35fde067e6a6bdc24aa9d44962235a071cec49904d1589e298c23dcd3"}, - {file = "netCDF4-1.6.5-cp38-cp38-win_amd64.whl", hash = "sha256:2c210794d96431d92b5992e46ad8a9f97237bf6d6956f8816978a03dc0fa18c3"}, - {file = "netCDF4-1.6.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:18255b8b283d32d3900092f29c67e53aa25bd8f0dfe7adde59fe782d865a381c"}, - {file = "netCDF4-1.6.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:53050562bac84738bbd121fbbee9593d074579f5d6fdaafcb981abeb5c964225"}, - {file = "netCDF4-1.6.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:938c062382406bca9198b16adddd87c09b00521766b138cdfd11c95546eefeb8"}, - {file = "netCDF4-1.6.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a8300451d7542d3c4ff1dcccf5fb1c7d44bdd1dc08ec77dab04416caf13cb1f"}, - {file = "netCDF4-1.6.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27db2701feef31201c9b20b04a9579196edc20dfc339ca423c7b81e462d6e14"}, - {file = "netCDF4-1.6.5-cp39-cp39-win_amd64.whl", hash = "sha256:574d7742ab321e5f9f33b5b1296c4ad4e5c469152c17d4fc453d5070e413e596"}, - {file = "netCDF4-1.6.5.tar.gz", hash = "sha256:824881d0aacfde5bd982d6adedd8574259c85553781e7b83e0ce82b890bfa0ef"}, + {file = "netCDF4-1.7.1.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5abdc8ab27bcb11325547841311717a0ba8f5b73a5fc5e93b933bc23285d0c03"}, + {file = "netCDF4-1.7.1.post1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:33f5d66ee9cedf43d3932d0e5447eb471f9c53332f93476133b4bfc6b682f790"}, + {file = "netCDF4-1.7.1.post1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d649fad9d1f63e25a191576c7de158c8c3afa8d4b4001e8683e20da90b49b939"}, + {file = "netCDF4-1.7.1.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:860222bc57bbc714e55705f263162be2c935129dcb700a944bda61aee785ff03"}, + {file = "netCDF4-1.7.1.post1-cp310-cp310-win_amd64.whl", hash = "sha256:d5420155ca6c768c070922d80acd9f4088a913afd25a9fd2f429e7af626374eb"}, + {file = "netCDF4-1.7.1.post1-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:a8d3209516aa8c58d70863ab1059af4ec82ef8ecb1c6b8cb4842d7825a6f64da"}, + {file = "netCDF4-1.7.1.post1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:7a10da9b60d3358876d53a0cd691d2c900c2b39903bf25ad5235fd321d59eb2f"}, + {file = "netCDF4-1.7.1.post1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac99e03d6e28419b206444fd6dc80a5e21d0ae8e53ff37d756fbc16c5d3775"}, + {file = "netCDF4-1.7.1.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e15f3afa4e6910fc158a318ea73fdc6f9e41058c71bf98a99fd63994334d16b0"}, + {file = "netCDF4-1.7.1.post1-cp311-cp311-win_amd64.whl", hash = "sha256:115160fc8e09333754542c33d721d42625a7bd62381a74f2f759297e3e38810b"}, + {file = "netCDF4-1.7.1.post1-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:75bba24ef0354fb6913bc3acdcb3790534e86bf329bbeaaf54122b18e5fd05ea"}, + {file = "netCDF4-1.7.1.post1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:ce7f89b98dbb3acd9582db30e6478ce7a7003b2cb70dc20d85fe9506e65ab001"}, + {file = "netCDF4-1.7.1.post1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac4e30a0d5a8e227d6a890502cfa201388acf606c0c73a5a7594232f3a74e67e"}, + {file = "netCDF4-1.7.1.post1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:988c45f9122337a12267fb158953c0609e3ea50a557335a3105f104416a4821a"}, + {file = "netCDF4-1.7.1.post1-cp312-cp312-win_amd64.whl", hash = "sha256:8fb3ed3541fa1b5b46e9d92d7e803734a1a3f37d8f5adf5fdf7957c7750cb20e"}, + {file = "netCDF4-1.7.1.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:a4d05cc4c3628a7b88d623cb1a02908100a4938335a0289fa79c19016c21d7f9"}, + {file = "netCDF4-1.7.1.post1-cp38-cp38-macosx_14_0_arm64.whl", hash = "sha256:3a9ba8dc93f3d9019db921e42d40fa6791e7e244f3bb3a874bf2bfb96aea7380"}, + {file = "netCDF4-1.7.1.post1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fbbca82a822ba74b605254f7a267d258f13d67f8a4156a09e26322bfa002a82d"}, + {file = "netCDF4-1.7.1.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a09da245f4784421fb4d5740dae0367cdbb270d0a931a33474ec17a9433314d"}, + {file = "netCDF4-1.7.1.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:fdcec3a3150f9248e76301ad723f51955efc770edf015dfb61a6480cc7c04a70"}, + {file = "netCDF4-1.7.1.post1-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:0fed0eb65a7751a99a0cee08c6df383737d46d17c73cabae81d113f1b4fa3643"}, + {file = "netCDF4-1.7.1.post1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daa6169fe6617a4612cb75a8ef61ee14011a012633ad1ace1b629a1ff87bf5cf"}, + {file = "netCDF4-1.7.1.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcad21e965978cc5530131bd7e73dcabe7dda1f681f9e4ebf940a65a176d25fe"}, + {file = "netCDF4-1.7.1.post1-cp39-cp39-win_amd64.whl", hash = "sha256:f24027ae19b68cc1274aad8b00d6d81879d506ddca011a080dff2117014398b9"}, + {file = "netcdf4-1.7.1.post1.tar.gz", hash = "sha256:797f0b25d87827fc6821e415d9e15a2068604b18c3be62563e72682bcba76548"}, ] [package.dependencies] @@ -1107,18 +1090,15 @@ tests = ["Cython", "packaging", "pytest"] [[package]] name = "nodeenv" -version = "1.8.0" +version = "1.9.1" description = "Node.js virtual environment builder" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] -[package.dependencies] -setuptools = "*" - [[package]] name = "numcodecs" version = "0.12.1" @@ -1206,13 +1186,13 @@ files = [ [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -1305,13 +1285,13 @@ testing = ["docopt", "pytest"] [[package]] name = "partd" -version = "1.4.1" +version = "1.4.2" description = "Appendable key-value storage" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "partd-1.4.1-py3-none-any.whl", hash = "sha256:27e766663d36c161e2827aa3e28541c992f0b9527d3cca047e13fb3acdb989e6"}, - {file = "partd-1.4.1.tar.gz", hash = "sha256:56c25dd49e6fea5727e731203c466c6e092f308d8f0024e199d02f6aa2167f67"}, + {file = "partd-1.4.2-py3-none-any.whl", hash = "sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f"}, + {file = "partd-1.4.2.tar.gz", hash = "sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c"}, ] [package.dependencies] @@ -1319,7 +1299,7 @@ locket = "*" toolz = "*" [package.extras] -complete = ["blosc", "numpy (>=1.9.0)", "pandas (>=0.19.0)", "pyzmq"] +complete = ["blosc", "numpy (>=1.20.0)", "pandas (>=1.3)", "pyzmq"] [[package]] name = "pexpect" @@ -1337,37 +1317,19 @@ ptyprocess = ">=0.5" [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] - -[[package]] -name = "portalocker" -version = "2.8.2" -description = "Wraps the portalocker recipe for easy usage" -optional = false -python-versions = ">=3.8" -files = [ - {file = "portalocker-2.8.2-py3-none-any.whl", hash = "sha256:cfb86acc09b9aa7c3b43594e19be1345b9d16af3feb08bf92f23d4dce513a28e"}, - {file = "portalocker-2.8.2.tar.gz", hash = "sha256:2b035aa7828e46c58e9b31390ee1f169b98e1066ab10b9a6a861fe7e25ee4f33"}, -] - -[package.dependencies] -pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} - -[package.extras] -docs = ["sphinx (>=1.7.1)"] -redis = ["redis"] -tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)", "types-redis"] +type = ["mypy (>=1.8)"] [[package]] name = "pre-commit" @@ -1389,13 +1351,13 @@ virtualenv = ">=20.10.0" [[package]] name = "prompt-toolkit" -version = "3.0.43" +version = "3.0.47" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, - {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, ] [package.dependencies] @@ -1428,28 +1390,27 @@ tests = ["pytest"] [[package]] name = "pygments" -version = "2.17.2" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pystac" -version = "1.10.0" +version = "1.10.1" description = "Python library for working with the SpatioTemporal Asset Catalog (STAC) specification" optional = false python-versions = ">=3.9" files = [ - {file = "pystac-1.10.0-py3-none-any.whl", hash = "sha256:2d1eb969abc7e13e2bdb4bb5ae1a68780da1e06f30f66fcf0d4143f51eb03f38"}, - {file = "pystac-1.10.0.tar.gz", hash = "sha256:e2762a700953ae9bab914137116cea31e08378f6c7024d805d651009a6341e20"}, + {file = "pystac-1.10.1-py3-none-any.whl", hash = "sha256:a7c31b3dacc44dfc955d9da8c7351c7b5b99100254b36301a1e312709b51bf2f"}, + {file = "pystac-1.10.1.tar.gz", hash = "sha256:4617fe5315a79785f79b616b8ac248ba3d4d561457c8300b34573309715808cd"}, ] [package.dependencies] @@ -1489,29 +1450,6 @@ files = [ {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -optional = false -python-versions = "*" -files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -1574,13 +1512,13 @@ files = [ [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -1623,19 +1561,18 @@ files = [ [[package]] name = "setuptools" -version = "69.5.1" +version = "70.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, - {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, + {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, + {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -1680,13 +1617,13 @@ files = [ [[package]] name = "tqdm" -version = "4.66.2" +version = "4.66.4" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, - {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, + {file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"}, + {file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"}, ] [package.dependencies] @@ -1727,6 +1664,20 @@ files = [ [package.dependencies] types-urllib3 = "*" +[[package]] +name = "types-requests" +version = "2.32.0.20240622" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-requests-2.32.0.20240622.tar.gz", hash = "sha256:ed5e8a412fcc39159d6319385c009d642845f250c63902718f605cd90faade31"}, + {file = "types_requests-2.32.0.20240622-py3-none-any.whl", hash = "sha256:97bac6b54b5bd4cf91d407e62f0932a74821bc2211f22116d9ee1dd643826caf"}, +] + +[package.dependencies] +urllib3 = ">=2" + [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -1740,13 +1691,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -1762,13 +1713,13 @@ files = [ [[package]] name = "urllib3" -version = "1.26.18" +version = "1.26.19" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, - {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, + {file = "urllib3-1.26.19-py2.py3-none-any.whl", hash = "sha256:37a0344459b199fce0e80b0d3569837ec6b6937435c5244e7fd73fa6006830f3"}, + {file = "urllib3-1.26.19.tar.gz", hash = "sha256:3e3d753a8618b86d7de333b4223005f68720bcd6a7d2bcb9fbd2229ec7c1e429"}, ] [package.extras] @@ -1776,15 +1727,32 @@ brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotl secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "virtualenv" -version = "20.25.3" +version = "20.26.3" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.3-py3-none-any.whl", hash = "sha256:8aac4332f2ea6ef519c648d0bc48a5b1d324994753519919bddbb1aff25a104e"}, - {file = "virtualenv-20.25.3.tar.gz", hash = "sha256:7bb554bbdfeaacc3349fa614ea5bff6ac300fc7c335e9facf3a3bcfc703f45be"}, + {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, + {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, ] [package.dependencies] @@ -1796,47 +1764,6 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] -[[package]] -name = "watchdog" -version = "4.0.0" -description = "Filesystem events monitoring" -optional = false -python-versions = ">=3.8" -files = [ - {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, - {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, - {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, - {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, - {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, - {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, - {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, - {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, - {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, - {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, -] - -[package.extras] -watchmedo = ["PyYAML (>=3.10)"] - [[package]] name = "wcwidth" version = "0.2.13" @@ -1850,24 +1777,24 @@ files = [ [[package]] name = "xarray" -version = "2024.3.0" +version = "2024.6.0" description = "N-D labeled arrays and datasets in Python" optional = false python-versions = ">=3.9" files = [ - {file = "xarray-2024.3.0-py3-none-any.whl", hash = "sha256:ca2bc4da2bf2e7879e15862a7a7c3fc76ad19f6a08931d030220cef39a29118d"}, - {file = "xarray-2024.3.0.tar.gz", hash = "sha256:5c1db19efdde61db7faedad8fc944f4e29698fb6fbd578d352668b63598bd1d8"}, + {file = "xarray-2024.6.0-py3-none-any.whl", hash = "sha256:721a7394e8ec3d592b2d8ebe21eed074ac077dc1bb1bd777ce00e41700b4866c"}, + {file = "xarray-2024.6.0.tar.gz", hash = "sha256:0b91e0bc4dc0296947947640fe31ec6e867ce258d2f7cbc10bedf4a6d68340c7"}, ] [package.dependencies] numpy = ">=1.23" -packaging = ">=22" -pandas = ">=1.5" +packaging = ">=23.1" +pandas = ">=2.0" [package.extras] accel = ["bottleneck", "flox", "numbagg", "opt-einsum", "scipy"] complete = ["xarray[accel,dev,io,parallel,viz]"] -dev = ["hypothesis", "pre-commit", "pytest", "pytest-cov", "pytest-env", "pytest-timeout", "pytest-xdist", "ruff", "xarray[complete]"] +dev = ["hypothesis", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-env", "pytest-timeout", "pytest-xdist", "ruff", "xarray[complete]"] io = ["cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "scipy", "zarr"] parallel = ["dask[complete]"] viz = ["matplotlib", "nc-time-axis", "seaborn"] @@ -1977,13 +1904,13 @@ multidict = ">=4.0" [[package]] name = "zarr" -version = "2.17.2" +version = "2.18.2" description = "An implementation of chunked, compressed, N-dimensional arrays for Python" optional = false python-versions = ">=3.9" files = [ - {file = "zarr-2.17.2-py3-none-any.whl", hash = "sha256:70d7cc07c24280c380ef80644151d136b7503b0d83c9f214e8000ddc0f57f69b"}, - {file = "zarr-2.17.2.tar.gz", hash = "sha256:2cbaa6cb4e342d45152d4a7a4b2013c337fcd3a8e7bc98253560180de60552ce"}, + {file = "zarr-2.18.2-py3-none-any.whl", hash = "sha256:a638754902f97efa99b406083fdc807a0e2ccf12a949117389d2a4ba9b05df38"}, + {file = "zarr-2.18.2.tar.gz", hash = "sha256:9bb393b8a0a38fb121dbb913b047d75db28de9890f6d644a217a73cf4ae74f47"}, ] [package.dependencies] @@ -1998,20 +1925,24 @@ jupyter = ["ipytree (>=0.2.2)", "ipywidgets (>=8.0.0)", "notebook"] [[package]] name = "zipp" -version = "3.18.1" +version = "3.19.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, - {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, + {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, + {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" +<<<<<<< HEAD content-hash = "df93116d25a101d3f319a1e497b4436a09702719616a853437524aa68acf47bd" +======= +content-hash = "f781539aa6604250d8715e3c6ef09165d031fbb95565f65e4368e41db7c50290" +>>>>>>> 95d6892 (chore: refactor to stop using the cache (#95)) diff --git a/pyproject.toml b/pyproject.toml index 315aeb41..a1afb294 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,6 @@ click = ">=8.0.4" requests = ">=2.27.1" aiohttp = ">=3.9.4,<3.10.0" setuptools = ">=68.2.2" -cachier = ">=2.2.1" xarray = ">=2023.4.0" tqdm = ">=4.65.0" zarr = ">=2.13.3" diff --git a/tests/__snapshots__/test_describe_released_date.ambr b/tests/__snapshots__/test_describe_released_date.ambr index 9f1cad13..b9e4fd04 100644 --- a/tests/__snapshots__/test_describe_released_date.ambr +++ b/tests/__snapshots__/test_describe_released_date.ambr @@ -6,7 +6,7 @@ 'datasets': list([ dict({ 'dataset_id': 'cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m', - 'dataset_name': 'cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m', + 'dataset_name': 'daily mean fields from Global Ocean Physics Analysis and Forecast updated Daily', 'versions': list([ dict({ 'label': '202211', @@ -2606,7 +2606,7 @@ 'datasets': list([ dict({ 'dataset_id': 'cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m', - 'dataset_name': 'cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m', + 'dataset_name': 'daily mean fields from Global Ocean Physics Analysis and Forecast updated Daily', 'versions': list([ dict({ 'label': '202211', diff --git a/tests/__snapshots__/test_help_command_interface.ambr b/tests/__snapshots__/test_help_command_interface.ambr index 7de4ae35..66ccbfb9 100644 --- a/tests/__snapshots__/test_help_command_interface.ambr +++ b/tests/__snapshots__/test_help_command_interface.ambr @@ -42,13 +42,6 @@ ' versions.', ' -c, --contains TEXT Filter catalogue output. Returns products', ' with attributes matching a string token.', - ' --overwrite-metadata-cache Force to refresh the catalogue by', - ' overwriting the local cache.', - ' \\x08 NOTE: This argument is mutually exclusive', - ' with arguments: [no_metadata_cache].', - ' --no-metadata-cache Bypass the use of cache. \\x08', - ' NOTE: This argument is mutually exclusive', - ' with arguments: [overwrite_metadata_cache].', ' --disable-progress-bar Flag to hide progress bar.', ' --log-level [DEBUG|INFO|WARN|ERROR|CRITICAL|QUIET]', ' Set the details printed to console by the', @@ -69,14 +62,12 @@ '', ' Download originally produced data files.', '', - ' Either one of --dataset-id or --dataset-url is required (can be found via', - ' the "describe" command). The function fetches the files recursively if a', - ' folder path is passed as URL. When provided a datasetID, all the files in', - ' the corresponding folder will be downloaded if none of the --filter or', - ' --regex options is specified.', + ' --dataset-id is required (can be found via the "describe" command). The', + ' function fetches the files recursively if a folder path is passed as URL.', + ' When provided a datasetID, all the files in the corresponding folder will be', + ' downloaded if none of the --filter or --regex options is specified.', '', 'Options:', - ' -u, --dataset-url TEXT URL to the data files.', ' -i, --dataset-id TEXT The datasetID.', ' --dataset-version, --force-dataset-version TEXT', ' Force the selection of a specific dataset', @@ -123,13 +114,6 @@ ' arguments. The file MUST follow the', " structure of dataclass \\'GetRequest\\'. For", ' more information please refer to the README.', - ' --overwrite-metadata-cache Force to refresh the catalogue by', - ' overwriting the local cache.', - ' \\x08 NOTE: This argument is mutually exclusive', - ' with arguments: [no_metadata_cache].', - ' --no-metadata-cache Bypass the use of cache. \\x08', - ' NOTE: This argument is mutually exclusive', - ' with arguments: [overwrite_metadata_cache].', ' --filter, --filter-with-globbing-pattern TEXT', ' A pattern that must match the absolute paths', ' of the files to download.', @@ -223,13 +207,12 @@ '', ' Download subsets of datasets as NetCDF files or Zarr stores.', '', - ' Either one of --dataset-id or --dataset-url is required (can be found via', - ' the "describe" command). The argument values passed individually through the', - ' CLI take precedence over the values from the --motu-api-request option,', - ' which takes precedence over the ones from the --request-file option.', + ' --dataset-id is required (can be found via the "describe" command). The', + ' argument values passed individually through the CLI take precedence over the', + ' values from the --motu-api-request option, which takes precedence over the', + ' ones from the --request-file option.', '', 'Options:', - ' -u, --dataset-url TEXT The full dataset URL.', ' -i, --dataset-id TEXT The datasetID.', ' --dataset-version, --force-dataset-version TEXT', ' Force the selection of a specific dataset', @@ -319,13 +302,6 @@ ' as a string. Caution, user has to replace', ' double quotes " with single quotes \\\' in the', ' request.', - ' --overwrite-metadata-cache Force to refresh the catalogue by', - ' overwriting the local cache.', - ' \\x08 NOTE: This argument is mutually exclusive', - ' with arguments: [no_metadata_cache].', - ' --no-metadata-cache Bypass the use of cache. \\x08', - ' NOTE: This argument is mutually exclusive', - ' with arguments: [overwrite_metadata_cache].', ' --disable-progress-bar Flag to hide progress bar.', ' --log-level [DEBUG|INFO|WARN|ERROR|CRITICAL|QUIET]', ' Set the details printed to console by the', diff --git a/tests/test_command_line_interface.py b/tests/test_command_line_interface.py index a7c4bd5c..101735d4 100644 --- a/tests/test_command_line_interface.py +++ b/tests/test_command_line_interface.py @@ -11,10 +11,9 @@ from pathlib import Path from typing import List, Optional, Union -import pytest import xarray -from copernicusmarine.catalogue_parser.catalogue_parser import ( +from copernicusmarine.catalogue_parser.models import ( PART_DEFAULT, REGEX_PATTERN_DATE_YYYYMM, VERSION_DEFAULT, @@ -54,13 +53,9 @@ def get_file_size(filepath): class TestCommandLineInterface: - @pytest.mark.order(1) - def test_describe_overwrite_metadata_cache(self): - self.when_I_run_copernicus_marine_describe_with_overwrite_cache() - self.then_stdout_can_be_load_as_json() - def test_describe_default(self): self.when_I_run_copernicus_marine_describe_with_default_arguments() + self.then_stdout_can_be_load_as_json() self.then_I_can_read_the_default_json() self.and_there_are_no_warnings_about_backend_versions() @@ -80,17 +75,9 @@ def test_describe_with_staging_flag(self): self.when_I_use_staging_environment_in_debug_logging_level() self.then_I_check_that_the_urls_contains_only_dta() - def when_I_run_copernicus_marine_describe_with_overwrite_cache(self): - command = [ - "copernicusmarine", - "describe", - "--overwrite-metadata-cache", - ] - self.output = execute_in_terminal(command) - def when_I_run_copernicus_marine_describe_with_default_arguments(self): command = ["copernicusmarine", "describe"] - self.output = execute_in_terminal(command) + self.output = execute_in_terminal(command, timeout_second=30) def then_stdout_can_be_load_as_json(self): loads(self.output.stdout.decode("utf-8")) @@ -222,7 +209,7 @@ def when_I_run_copernicus_marine_describe_with_contains_option(self): "--contains", f"{filter_token}", ] - self.output = execute_in_terminal(command) + self.output = execute_in_terminal(command, timeout_second=30) def then_I_can_read_the_filtered_json(self): json_result = loads(self.output.stdout) @@ -261,7 +248,7 @@ def when_I_run_copernicus_marine_describe_including_datasets(self): "describe", "--include-datasets", ] - self.output = execute_in_terminal(command) + self.output = execute_in_terminal(command, timeout_second=30) def then_I_can_read_it_does_not_contain_weird_symbols(self): assert b"__" not in self.output.stdout @@ -385,7 +372,6 @@ def when_I_use_staging_environment_in_debug_logging_level(self): "--staging", "--log-level", "DEBUG", - "--no-metadata-cache", ] self.output = execute_in_terminal(command) @@ -454,11 +440,6 @@ def _test_subset_functionnalities( self.check_default_subset_request( subset_service_to_test.subpath, tmp_path ) - self.check_subset_request_with_dataseturl( - subset_service_to_test.subpath, - subset_service_to_test.dataset_url, - tmp_path, - ) self.check_subset_request_with_dataset_not_in_catalog() self.check_subset_request_with_no_subsetting() @@ -476,25 +457,6 @@ def check_default_subset_request(self, function_name, tmp_path): self.output = execute_in_terminal(command) assert self.output.returncode == 0 - def check_subset_request_with_dataseturl( - self, function_name, dataset_url, tmp_path - ): - folder = pathlib.Path(tmp_path, function_name) - if not folder.is_dir(): - pathlib.Path.mkdir(folder, parents=True) - - self.base_request_dict.pop("--dataset-id") - self.base_request_dict["--dataset-url"] = f"{dataset_url}" - - command = [ - "copernicusmarine", - "subset", - "--force-download", - ] + self.flatten_request_dict(self.base_request_dict) - - self.output = execute_in_terminal(command) - assert self.output.returncode == 0 - def check_subset_request_with_dataset_not_in_catalog(self): self.base_request_dict["--dataset-id"] = "FAKE_ID" self.base_request_dict.pop("--dataset-url") @@ -996,48 +958,6 @@ def then_I_got_a_clear_output_with_available_service_for_subset(self): b"'arco-time-series', 'timeseries', 'omi-arco', 'static-arco']" ) in self.output.stderr - def test_mutual_exclusivity_of_cache_options_for_describe(self): - self.when_I_run_copernicus_marine_command_with_both_cache_options( - "describe" - ) - self.then_I_got_an_error_regarding_mutual_exclusivity() - - def test_mutual_exclusivity_of_cache_options_for_get(self): - self.when_I_run_copernicus_marine_command_with_both_cache_options( - "get" - ) - self.then_I_got_an_error_regarding_mutual_exclusivity() - - def test_mutual_exclusivity_of_cache_options_for_subset(self): - self.when_I_run_copernicus_marine_command_with_both_cache_options( - "subset" - ) - self.then_I_got_an_error_regarding_mutual_exclusivity() - - def when_I_run_copernicus_marine_command_with_both_cache_options( - self, command_option - ): - command = [ - "copernicusmarine", - f"{command_option}", - "--overwrite-metadata-cache", - "--no-metadata-cache", - ] - self.output = execute_in_terminal(command) - - def then_I_got_an_error_regarding_mutual_exclusivity(self): - assert self.output.returncode == 2 - assert self.output.stdout == b"" - assert self.output.stderr == ( - b"Error: Illegal usage: `overwrite-metadata-cache` is mutually " - b"exclusive with arguments `no-metadata-cache`.\n" - ) - - def test_describe_without_using_cache(self): - command = ["copernicusmarine", "describe", "--no-metadata-cache"] - self.output = execute_in_terminal(command=command, timeout_second=30) - assert self.output.returncode == 0 - def when_I_request_subset_dataset_with_zarr_service( self, output_path, vertical_dimension_as_originally_produced ): @@ -1240,6 +1160,7 @@ def then_I_can_see_the_arco_geo_series_service_is_choosen(self): in self.output.stderr ) +<<<<<<< HEAD def test_subset_with_dataset_id_and_url(self): command = [ "copernicusmarine", @@ -1274,6 +1195,8 @@ def test_no_traceback_is_printed_on_dataset_url_error(self): assert self.output.returncode == 1 assert b"Traceback" not in self.output.stderr +======= +>>>>>>> 95d6892 (chore: refactor to stop using the cache (#95)) def test_get_2023_08_original_files(self): command = [ "copernicusmarine", @@ -1321,6 +1244,7 @@ def test_subset_with_chunking(self, tmp_path): assert self.output.returncode == 0 +<<<<<<< HEAD def test_dataset_url_suffix_path_are_used_as_filter(self): command = [ "copernicusmarine", @@ -1335,6 +1259,8 @@ def test_dataset_url_suffix_path_are_used_as_filter(self): assert b"Printed 20 out of 30 files" in self.output.stderr +======= +>>>>>>> 95d6892 (chore: refactor to stop using the cache (#95)) def test_short_option_for_copernicus_marine_command_helper(self): short_option_command = [ "copernicusmarine", @@ -1919,50 +1845,6 @@ def test_netcdf_compression_level(self, tmp_path): assert dataset.uo.encoding["contiguous"] is False assert dataset.uo.encoding["shuffle"] is True - def test_that_cache_folder_isnt_created_when_no_metadata_cache_option_was_provided( - self, tmp_path - ): - dataset_id = "cmems_mod_ibi_phy_my_0.083deg-3D_P1Y-m" - output_filename = "test_subset_output_file_as_netcdf.nc" - cache_directory = f"{tmp_path}" - - os.environ["COPERNICUSMARINE_CACHE_DIRECTORY"] = cache_directory - - command = [ - "copernicusmarine", - "subset", - "--dataset-id", - f"{dataset_id}", - "--variable", - "thetao", - "--minimum-longitude", - "-9.9", - "--maximum-longitude", - "-9.6", - "--minimum-latitude", - "33.96", - "--maximum-latitude", - "34.2", - "--minimum-depth", - "0.5", - "--maximum-depth", - "1.6", - "-o", - f"{tmp_path}", - "-f", - f"{output_filename}", - "--force-download", - ] - - execute_in_terminal(command + ["--no-metadata-cache"]) - cache_path = Path(tmp_path) / Path(".copernicusmarine") / Path("cache") - assert cache_path.is_dir() is False - - execute_in_terminal(command) - assert cache_path.is_dir() is True - - del os.environ["COPERNICUSMARINE_CACHE_DIRECTORY"] - def test_file_list_filter(self, tmp_path): dataset_id = "cmems_obs-sl_glo_phy-ssh_nrt_allsat-l4-duacs-0.25deg_P1D" command = [ diff --git a/tests/test_describe_released_date.py b/tests/test_describe_released_date.py index b20044f5..9c538783 100644 --- a/tests/test_describe_released_date.py +++ b/tests/test_describe_released_date.py @@ -17,7 +17,6 @@ def when_I_describe_the_marine_data_store( include_versions=False, ): return describe( - no_metadata_cache=True, include_versions=include_versions, include_datasets=True, ) diff --git a/tests/test_python_interface.py b/tests/test_python_interface.py index 5cf14ed7..d4cb3bbc 100644 --- a/tests/test_python_interface.py +++ b/tests/test_python_interface.py @@ -119,9 +119,7 @@ def test_login_not_ok_with_wrong_credentials(self, tmp_path): assert non_existing_directory.is_dir() is False def test_signature_inspection_is_working(self): - assert inspect.signature(describe).parameters[ - "overwrite_metadata_cache" - ] + assert inspect.signature(describe).parameters["contains"] common_key_parameter = "username" assert inspect.signature(login).parameters[common_key_parameter] diff --git a/tests/test_versions_parts_sorting.py b/tests/test_versions_parts_sorting.py index bb09cf6a..b45356ba 100644 --- a/tests/test_versions_parts_sorting.py +++ b/tests/test_versions_parts_sorting.py @@ -1,4 +1,4 @@ -from copernicusmarine.catalogue_parser.catalogue_parser import ( +from copernicusmarine.catalogue_parser.models import ( PART_DEFAULT, VERSION_DEFAULT, CopernicusMarineDatasetVersion, diff --git a/tests_dependencie_versions/test_basic_commands.py b/tests_dependencie_versions/test_basic_commands.py index c3803fc8..e8c57095 100644 --- a/tests_dependencie_versions/test_basic_commands.py +++ b/tests_dependencie_versions/test_basic_commands.py @@ -9,7 +9,6 @@ def test_describe(self): command = [ "copernicusmarine", "describe", - "--overwrite-metadata-cache", ] self.output = execute_in_terminal(command)