def read_iiasa(name, meta=False, creds=None, base_url=_BASE_URL, **kwargs): """ Query an IIASA database. See Connection.query() for more documentation Parameters ---------- name : str A valid IIASA database name, see pyam.iiasa.valid_connections() meta : bool or list of strings If not False, also include metadata indicators (or subset if provided). creds : dict Credentials to access IXMP and authentication service APIs (username/password) base_url: str Authentication server URL kwargs : Arguments for pyam.iiasa.Connection.query() """ conn = Connection(name, creds, base_url) # data df = conn.query(**kwargs) df = IamDataFrame(df) # metadata if meta: mdf = conn.metadata() # only data for models/scenarios in df mdf = mdf[mdf.model.isin(df['model'].unique()) & mdf.scenario.isin(df['scenario'].unique())] # get subset of data if meta is a list if islistable(meta): mdf = mdf[['model', 'scenario'] + meta] mdf = mdf.set_index(['model', 'scenario']) # we have to loop here because `set_meta()` can only take series for col in mdf: df.set_meta(mdf[col]) return df
def read_iiasa(name, meta=False, creds=None, base_url=_BASE_URL, **kwargs): """Read data from an IIASA scenario explorer and return as IamDataFrame Parameters ---------- name : str A valid name of an IIASA scenario explorer instance, see :attr:`pyam.iiasa.Connection.valid_connections` meta : bool or list of strings If :obj:`True`, include all meta categories & quantitative indicators (or subset if list is given). creds : dict Credentials to access scenario explorer instance and authentication service APIs (username/password) base_url : str Authentication server URL kwargs Arguments for :meth:`pyam.iiasa.Connection.query` """ conn = Connection(name, creds, base_url) # data df = IamDataFrame(conn.query(**kwargs)) # meta: categorization and quantitative indications if meta: mdf = conn.metadata() # only data for models/scenarios in df mdf = mdf[mdf.model.isin(df['model'].unique()) & mdf.scenario.isin(df['scenario'].unique())] # get subset of data if meta is a list if islistable(meta): mdf = mdf[['model', 'scenario'] + meta] mdf = mdf.set_index(['model', 'scenario']) # we have to loop here because `set_meta()` can only take series for col in mdf: df.set_meta(mdf[col]) return df
def query(self, default=True, meta=True, **kwargs): """Query the connected resource for timeseries data (with filters) Parameters ---------- default : bool, optional Return *only* the default version of each scenario. Any (`model`, `scenario`) without a default version is omitted. If :obj:`False`, return all versions. meta : bool or list, optional If :obj:`True`, merge all meta columns indicators (or subset if list is given). kwargs Available keyword arguments include - model - scenario - region - variable Returns ------- IamDataFrame Examples -------- You can read from a :class:`pyam.iiasa.Connection` instance using keyword arguments similar to filtering an :class:`IamDataFrame`: .. code-block:: python Connection.query(model='MESSAGE*', scenario='SSP2*', variable=['Emissions|CO2', 'Primary Energy']) """ headers = { "Authorization": "Bearer {}".format(self._token), "Content-Type": "application/json", } # retrieve meta (with run ids) or only index if meta: _meta = self.meta(default=default, run_id=True) # downselect to subset of meta columns if given as list if islistable(meta): # always merge 'version' (even if not requested explicitly) # 'run_id' is required to determine `_args`, dropped later _meta = _meta[set(meta).union(["version", "run_id"])] else: _meta = self._query_index( default=default).set_index(DEFAULT_META_INDEX) # retrieve data _args = json.dumps(self._query_post(_meta, default=default, **kwargs)) url = "/".join([self._auth_url, "runs/bulk/ts"]) logger.debug(f"Query timeseries data from {url} with data {_args}") r = requests.post(url, headers=headers, data=_args) _check_response(r) # refactor returned json object to be castable to an IamDataFrame dtype = dict( model=str, scenario=str, variable=str, unit=str, region=str, year=int, value=float, version=int, ) data = pd.read_json(r.text, orient="records", dtype=dtype) logger.debug(f"Response: {len(r.text)} bytes, {len(data)} records") cols = IAMC_IDX + ["year", "value", "subannual", "version"] # keep only known columns or init empty df data = pd.DataFrame(data=data, columns=cols) # check if timeseries data has subannual disaggregation, drop if not if "subannual" in data: timeslices = data.subannual.dropna().unique() if all([i in [-1, "Year"] for i in timeslices]): data.drop(columns="subannual", inplace=True) # define the index for the IamDataFrame if default: index = DEFAULT_META_INDEX data.drop(columns="version", inplace=True) else: index = DEFAULT_META_INDEX + ["version"] logger.info("Initializing an `IamDataFrame` " f"with non-default index {index}") # merge meta indicators (if requested) and cast to IamDataFrame if meta: # 'run_id' is necessary to retrieve data, not returned by default if not (islistable(meta) and "run_id" in meta): _meta.drop(columns="run_id", inplace=True) return IamDataFrame(data, meta=_meta, index=index) else: return IamDataFrame(data, index=index)