2121
2222__all__ = ["net_present_value" , "income_group" , "gdp" ]
2323
24+ import json
2425import logging
2526import shutil
2627import warnings
3132import pandas as pd
3233import requests
3334from cartopy .io import shapereader
34- from pandas_datareader import wb
3535
3636from climada .util .constants import SYSTEM_DIR
3737from climada .util .files_handler import download_file
@@ -181,6 +181,68 @@ def gdp(cntry_iso, ref_year, shp_file=None, per_capita=False):
181181 return close_year , close_val
182182
183183
184+ def download_world_bank_indicator (
185+ country_code : str , indicator : str , parse_dates : bool = False
186+ ):
187+ """Download indicator data from the World Bank API for all years or dates on record
188+
189+ Parameters
190+ ----------
191+ country_code : str
192+ The country code in ISO alpha 3
193+ indicator : str
194+ The ID of the indicator in the World Bank API
195+ parse_dates : bool
196+ Whether the dates of the indicator data should be parsed as datetime objects.
197+ If ``False`` (default), they will be parsed as ``int`` (this only works for
198+ yearly data).
199+
200+ Returns
201+ -------
202+ pd.Series
203+ A series with the values of the indicator for all dates (years) on record
204+ """
205+ # Download data from API
206+ raw_data = []
207+ pages = np .inf
208+ page = 1
209+ while page <= pages :
210+ response = requests .get (
211+ f"https://api.worldbank.org/v2/countries/{ country_code } /indicators/"
212+ f"{ indicator } ?format=json&page={ page } "
213+ )
214+ json_data = json .loads (response .text )
215+ print (json_data )
216+
217+ # Check if we received an error message
218+ try :
219+ if json_data [0 ]["message" ][0 ]["id" ] == "120" :
220+ raise RuntimeError (
221+ "Error requesting data from the World Bank API. Did you use the "
222+ "correct country code and indicator ID?"
223+ )
224+ # If no, we should be fine
225+ except KeyError :
226+ pass
227+
228+ # Update the data
229+ pages = json_data [0 ]["pages" ]
230+ page = page + 1
231+ raw_data .append (json_data [1 ])
232+
233+ # Create dataframe
234+ data = pd .concat ([pd .DataFrame .from_records (rec ) for rec in raw_data ])
235+
236+ # Parse dates and rename value column
237+ if parse_dates :
238+ data ["date" ] = pd .DatetimeIndex (data ["date" ])
239+ else :
240+ data ["date" ] = data ["date" ].astype ("int" )
241+
242+ # Only return indicator data (with a proper name)
243+ return data .set_index ("date" )["value" ].rename (data ["indicator" ].iloc [0 ]["value" ])
244+
245+
184246def world_bank (cntry_iso , ref_year , info_ind ):
185247 """Get country's GDP from World Bank's data at a given year, or
186248 closest year value. If no data, get the natural earth's approximation.
@@ -204,18 +266,14 @@ def world_bank(cntry_iso, ref_year, info_ind):
204266 IOError, KeyError, IndexError
205267 """
206268 if info_ind != "INC_GRP" :
207- with warnings .catch_warnings ():
208- warnings .simplefilter ("ignore" )
209- cntry_gdp = wb .download (
210- indicator = info_ind , country = cntry_iso , start = 1960 , end = 2030
211- )
212- years = np .array (
213- [int (year ) for year in cntry_gdp .index .get_level_values ("year" )]
269+ cntry_gdp = download_world_bank_indicator (
270+ indicator = info_ind , country_code = cntry_iso , parse_dates = False
214271 )
272+ years = cntry_gdp .index
215273 sort_years = np .abs (years - ref_year ).argsort ()
216274 close_val = cntry_gdp .iloc [sort_years ].dropna ()
217- close_year = int ( close_val .iloc [0 ]. name [ 1 ])
218- close_val = float (close_val .iloc [0 ]. values )
275+ close_year = close_val .index [0 ]
276+ close_val = float (close_val .iloc [0 ])
219277 else : # income group level
220278 fn_ig = SYSTEM_DIR .joinpath ("OGHIST.xls" )
221279 dfr_wb = pd .DataFrame ()
0 commit comments