Source code for esmvalcore.io

"""A modular system for reading input data from various sources."""

import importlib
import logging

from esmvalcore.config import Session
from esmvalcore.io.protocol import DataSource

logger = logging.getLogger(__name__)


[docs] def load_data_sources( session: Session, project: str | None = None, ) -> list[DataSource]: """Get the list of available data sources. Arguments --------- session: The configuration. project: If specified, only data sources for this project are returned. Returns ------- :obj:`list` of :obj:`DataSource`: A list of available data sources. Raises ------ ValueError: If the project or its settings are not found in the configuration. """ data_sources: list[DataSource] = [] if project is not None and project not in session["projects"]: msg = f"Unknown project '{project}', please configure it under 'projects'." raise ValueError(msg) settings = ( session["projects"] if project is None else {project: session["projects"][project]} ) for project_, project_settings in settings.items(): for name, orig_kwargs in project_settings.get("data", {}).items(): kwargs = orig_kwargs.copy() module_name, cls_name = kwargs.pop("type").rsplit(".", 1) module = importlib.import_module(module_name) cls = getattr(module, cls_name) priority = kwargs.pop("priority", 1) data_source = cls( name=name, project=project_, priority=priority, **kwargs, ) if not isinstance(data_source, DataSource): msg = ( "Expected a data source of type `esmvalcore.io.protocol.DataSource`, " f"but your configuration for project '{project_}' contains " f"'{data_source}' of type '{type(data_source)}'." ) raise TypeError(msg) data_sources.append(data_source) if not data_sources: if project is None: msg = "No data sources found. Check your configuration under 'projects'" else: msg = ( f"No data sources found for project '{project}'. " f"Check your configuration under 'projects: {project}: data'" ) raise ValueError(msg) return data_sources