def list(id='all', q=None, topic=None, db=None): '''Return a list of series elements in the current database Arguments: id: a series identifier (i.e., CETS code) or list-like q: search string (on series name) topic: topic ID or list-like db: database; pass None to access the global database Returns: a generator object Example: for elem in wbgapi.series.list(): print(elem['id'], elem['value']) ''' if( topic ): topics = w.topic.members(topic) if type(id) is str and id != 'all': # if id is also specified, then calculate the intersection of that and the series from topics id = set(w.queryParam(id, 'series', db=db).split(';')) id &= topics else: id = topics q,fullSearch = utils.qget(q) for row in w.source.features('series', w.queryParam(id, 'series', db=db), db=db): if utils.qmatch(q, row['value'], fullSearch): yield row
def list(id='all', q=None, group=None): '''Return a list of regions Arguments: id: a region identifier or list-like of identifiers q: search string (on region name) group: subgroup to return. Can be one of: 'admin', 'geo', 'allincomelevels', 'demodividend', 'smallstates', 'other' NB: technically possible to pass 'lending' but the returned values generally aren't useful Returns: a generator object Example: regions = {row['code']: row['name'] for row in wbgapi.region.list()} Notes: The region list is global to the entire API and is not specific to the current database. ''' params = {'type': group} if group else {} q, _ = utils.qget(q) for row in w.fetch('region/' + w.queryParam(id), params): if utils.qmatch(q, row['name']): yield row
def footnote(series, economy, time, db=None): '''Return the footnote for a single data point, if any Arguments: series: a series identifier economy: an economy identifier time: a time identifier. Both element keys and values are acceptable Returns: footnote text, or None Example: print(wbgapi.data.footnote('SP.POP.TOTL', 'FRA', 2015)) ''' if db is None: db = w.db # note that this only supports singular footnote references at this point, although the interface suggests otherwise url = 'sources/{source}/footnote/{economy}~{series}~{time}/metadata' try: for row in w.metadata(url, ['series'], source=db, series=series, economy=economy, time=w.queryParam(time, 'time', db=db)): return row.metadata['FootNote'] except: pass # will return None then
def list(id='all', q=None, labels=False, skipAggs=False, db=None): '''Return a list of economies in the current database Arguments: id: an economy identifier or list-like q: search string (on economy name) labels: return both codes and labels for regions, income and lending groups skipAggs: skip aggregates db: database: pass None to access the global database Returns: a generator object Example: for elem in wbgapi.economy.list(): print(elem['id'], elem[' value']) ''' q, _ = utils.qget(q) update_caches() for row in w.source.features('economy', w.queryParam(id, 'economy', db=db), db=db): _build(row,labels) if (skipAggs == False or row['aggregate'] == False) and utils.qmatch(q, row['value']): yield row
def list(id='all', q=None): '''Return a list of databases Arguments: id: a database identifier or list-like q: search string (on source name) Returns: a generator object Example: for elem in wbgapi.source.list(): print(elem['id'], elem['name'], elem['lastupdated']) ''' id = w.queryParam(id) if not id: return [] q,_ = utils.qget(q) for row in w.fetch(_sourceurl(id), {'databid': 'y'}): if utils.qmatch(q, row['name']): yield row
def is_single(x): if type(x) is str: if x == 'all': return False elif x == 'mrv': return True # not necessary to pass db since we don't actually care about the parameters just the count of them return len(w.queryParam(x).split(';')) == 1
def get(id): '''Retrieve the specified time element Arguments: id: the time identifier Returns: a time object Example: print(wbgapi.time.get('YR2015')['value']) ''' return w.source.feature('time', w.queryParam(id, 'time'))
def get(id): '''Retrieve the specified topic Arguments: id: the topic ID Returns: a topic object Example: print(wbgapi.topic.get(5)['value']) ''' return w.get('topic/' + w.queryParam(id))
def get(id): '''Retrieve the specified region Arguments: id: the region ID Returns: a region object Example: print(wbgapi.region.get('NAC')['name']) ''' return w.get('region/' + w.queryParam(id))
def get(id): '''Retrieve the specified income group Arguments: id: the income group ID Returns: an income group object Example: print(wbgapi.income.get('LIC')['name']) ''' return w.get('incomelevel/' + w.queryParam(id))
def get(id): '''Retrieve the specified lending group Arguments: id: the lending group ID Returns: a lending group object Example: print(wbgapi.lending.get('IBD')['value']) ''' return w.get('lendingtype/' + w.queryParam(id))
def list(id='all'): '''Return a list of lending groups Arguments: id: a lending group identifier or list-like of identifiers Returns: a generator object Example: lendingGroups = {row['id']: row['value'] for row in wbapi.lending.list()} ''' for row in w.fetch('lendingtype/' + w.queryParam(id)): yield row
def list(id='all'): '''Return a list of series elements in the current database Arguments: id: a series identifier (i.e., CETS code) or list-like Returns: a generator object Example: for elem in wbgapi.series.list(): print(elem['id'], elem['value']) ''' return w.source.features('series', w.queryParam(id, 'series'))
def get(id, db=None): '''Retrieve the specified time element Arguments: id: the time identifier db: database; pass None to access the global database Returns: a time object Example: print(wbgapi.time.get('YR2015')['value']) ''' return w.source.feature('time', w.queryParam(id, 'time', db=db), db=db)
def list(id='all'): '''Return a list of time elements in the current database Arguments: id: a time identifier or list-like Returns: a generator object Example: # fetch even-numbered time elements for a decade for elem in wbgapi.time.list(range(2010,2020,2)): print(elem['id'], elem['value']) ''' return w.source.features('time', w.queryParam(id, 'time'))
def members(id): '''Return a set of series identifiers that are members of the specified topic Arguments: id: a topic identifier Returns: a set object of series identifiers ''' e = set() for row in w.fetch('topic/{}/indicator'.format(w.queryParam(id)), {'source': w.db}): e.add(row['id']) return e
def list(id='all'): '''Return a list of databases Arguments: id: a database identifier or list-like Returns: a generator object Example: for elem in wbgapi.source.list(): print(elem['id'], elem['name'], elem['lastupdated']) ''' id = w.queryParam(id) if not id: return [] return w.fetch(_sourceurl(id), {'databid': 'y'})
def list(id='all', group=None): '''Return a list of regions Arguments: id: a region identifier or list-like of identifiers group: subgroup to return. Can be one of: 'admin', 'geo', 'allincomelevels', 'demodividend', 'smallstates', 'other' NB: technically possible to pass 'lending' but the returned values generally aren't useful Returns: a generator object Example: regions = {row['code']: row['name'] for row in wbgapi.region.list()} ''' params = {'type': group} if group else {} for row in w.fetch('region/' + w.queryParam(id), params): yield row
def list(id='all',labels=False,skipAggs=False): '''Return a list of economies in the current database Arguments: id: an economy identifier or list-like skipAggs: skip aggregates Returns: a generator object Example: for elem in wbgapi.economy.list(): print(elem['id'], elem[' value']) ''' global _class_data update_caches() for row in w.source.features('economy', w.queryParam(id, 'economy')): _build(row,labels) if skipAggs == False or row['aggregate'] == False: yield row
def footnote(series, economy, time): '''Return the footnote for a single data point, if any Arguments: series: a series identifier economy: an economy identifier time: a time identifier. Both element keys and values are acceptable Returns: footnote text, or None Example: print(wbgapi.data.footnote('SP.POP.TOTL', 'FRA', 2015)) ''' url = 'sources/{}/footnote/{}~{}~{}/metadata'.format( w.db, economy, series, w.queryParam(time, 'time')) try: for row in w.metadata(url): return row.metadata['FootNote'] except: pass # will return None then
def list(id='all', q=None): '''Return a list of lending groups Arguments: id: a lending group identifier or list-like of identifiers q: search string (on lending group name) Returns: a generator object Example: lendingGroups = {row['id']: row['value'] for row in wbapi.lending.list()} Notes: The lending group list is global to the entire API and is not specific to the current database. ''' q, _ = utils.qget(q) for row in w.fetch('lendingtype/' + w.queryParam(id)): if utils.qmatch(q, row['value']): yield row
def list(id='all', q=None, db=None): '''Return a list of time elements in the current database Arguments: id: a time identifier or list-like q: search string (on value name) db: database; pass None to access the global database Returns: a generator object Example: # fetch even-numbered time elements for a decade for elem in wbgapi.time.list(range(2010,2020,2)): print(elem['id'], elem['value']) ''' q,_ = utils.qget(q) for row in w.source.features('time', w.queryParam(id, 'time', db=db), db=db): if utils.qmatch(q, row['value']): yield row
def list(id='all', q=None): '''Return a list of topics Arguments: id: a region identifier or list-like of identifiers q: search string (on topic name) Returns: a generator object Example: topics = {row['value']: row['id'] for row in wbgapi.topic.list()} Notes: The topic list is global to the entire API and is not specific to the current database. ''' q, _ = utils.qget(q) for row in w.fetch('topic/' + w.queryParam(id)): if utils.qmatch(q, row['value']): yield row
def fetch(id, economies=[], time=[], db=None): '''Return metadata for specified series Arguments: id: a series identifier or list-like economies: optional list of economies for which to include series-economy metadata (NB: this is the same metadata returned by economy.metadata.fetch() with the series parameter) time: optional list of time identifiers for which to include series-time metadata db: database; pass None to access the global database Returns: A generator object which generates Metadata objects. If series/economy or series/time metadata are requested they will be stored on the 'economies' and 'time' properties Examples: for meta = wbgapi.series.metadata.fetch(['SP.POP.TOTL', 'NY.GDP.PCAP.CD']): print(meta) ''' if type(economies) is str: if economies == 'all': economies = [row['id'] for row in w.economy.list()] else: economies = [economies] if type(time) is str: if time == 'all': time = [row['id'] for row in w.time.list()] else: time = [time] if db is None: db = w.db if not w.source.has_metadata(db): return None for row in w.metadata('sources/{source}/series/{series}/metadata', ['series'], source=db, series=w.queryParam(id, 'series', db=db)): if economies: row.economies = {} # requests for non-existing data throw malformed responses so we must catch for them try: cs = ';'.join( ['{}~{}'.format(elem, row.id) for elem in economies]) for row2 in w.metadata( 'sources/{source}/Country-Series/{series}/metadata', ['series'], source=db, series=cs): row.economies[row2.id.split('~') [0]] = row2.metadata['Country-Series'] except: pass if time: row.time = {} try: st = ';'.join(['{}~{}'.format(row.id, elem) for elem in time]) for row2 in w.metdata( 'sources/{source}/Series-Time/{series}/metadata', ['series'], source=db, series=st): row.time[row2.id.split('~') [1]] = row2.metadata['Series-Time'] except: pass yield row
def is_single(x): if type(x) is str and x == 'all': return False return len(w.queryParam(x).split(';')) == 1
def fetch(id, series=[], db=None): '''Return metadata for the specified economy Arguments: id: an economy identifier or list-like series: optional list of series for which to include series-economy metadata (NB: this is the same metadata returned by series.metadata.fetch() with the economies parameter) db: database; pass None to access the global database Returns: a generator which generates Metadata objects. If series/economy metadata is requested it will be stored on the 'series' property of the object. Notes: Passing a large series list will be very resource intense and inefficient. It might be better to call series.metadata.fetch() with a relatively small list of countries Example: for meta = wbgapi.economy.metadata.fetch(['COL', 'BRA']): print(meta) ''' if db is None: db = w.db if not w.source.has_metadata(db): return None if type(series) is str: if series == 'all': # could be huge series = [row['id'] for row in w.series.list()] else: series = [series] # as far as I can tell even for databases where the dimension is called 'economy' or something else the metadata API still # wants 'country' as a parameter for row in w.metadata('sources/{source}/country/{economy}/metadata', ['economy'], source=db, economy=w.queryParam(id, 'economy', db=db)): if series: row.series = {} # requests for non-existing data throw malformed responses so we must catch for them try: cs = ';'.join([ '{}~{}'.format(row.id, elem) for elem in series[n:n + pg_size] ]) for row2 in w.metadata( 'sources/{source}/Country-Series/{series}/metadata', ['series'], source=db, series=cs): row.series[row2.id.split('~') [1]] = row2.metadata['Country-Series'] except: pass yield row
def fetch(series, economy='all', time='all', mrv=None, mrnev=None, skipBlanks=False, labels=False, skipAggs=False, numericTimeKeys=False, params={}, db=None, **dimensions): '''Retrieve rows of data for the current database Arguments: series: a series identifier or list-like, e.g., SP.POP.TOTL economy: an economy identifier or list-like, e.g., 'BRA' or ['USA', 'CAN', 'MEX'] time: a time identifier or list-like, e.g., 'YR2015' or range(2010,2020). Both element keys and values are acceptable mrv: return only the specified number of most recent values (same time period for all economies) mrnev: return only the specified number of non-empty most recent values (time period varies) skipBlanks: skip empty observations labels: include both dimension id and name (e.g., ZWE & Zimbabwe, not just ZWE) skipAggs: skip aggregates numericTimeKeys: store the time object by value (e.g., 2014) instead of key ('YR2014') if value is numeric params: extra query parameters to pass to the API dimensions: extra dimensions, database specific (e.g., version) Returns: A generator object Examples: # print name and population of all economies for all available years for elem in wbgapi.data.fetch('SP.POP.TOTL',labels=True): print(elem['economy']['value'], elem['time']['value'], elem['value']) # fetch data for Brazil for odd-numbered years for elem in wbgapi.data.fetch('NY.GDP.PCAP.CD', 'BRA', range(2011,2020,2)): print(elem['value']) # most recent poverty rates for all LAC countries for elem in wbgapi.data.fetch('SI.POV.NAHC', economy=wb.region.members('LAC'), mrnev=1): print(elem['economy'], elem['time'], elem['value']) # dict of most recent population data for economies over 100000 popData = {i['economy']: i['value'] for i in wbgapi.data.fetch('SP.POP.TOTL', mrnev=1, skipAggs=True) if i['value'] > 100000} ''' if db is None: db = w.db concepts = w.source.concepts(db) concept_keys = {v['key']: k for k, v in concepts.items()} params_ = {} params_.update(params) if mrv: params_['mrv'] = mrv elif mrnev: params_['mrnev'] = mrnev # you can thus pass series, economy, and time in the dimensions array, and those will overwrite the explicit parameters dimensions_ = {'series': series, 'economy': economy, 'time': time} dimensions_.update(dimensions) url = 'sources/{}'.format(db) keys = ['series', 'economy', 'time'] values = {} for k, v in dimensions_.items(): if k not in concepts: raise KeyError('{} is not a concept in database {}'.format(k, db)) if k not in keys: keys.append(k) url += '/{}/{}'.format(concepts[k]['key'], '{' + k + '}') values[k] = w.queryParam(v, concept=k, db=db) aggs = w.economy.aggregates() for row in w.refetch(url, keys, params=params_, **values): if skipBlanks and row['value'] is None: continue skip = False x = {'value': row['value']} for elem in row['variable']: key = concept_keys[elem['concept'].lower()] if key == 'economy' and skipAggs and elem['id'] in aggs: skip = True break if not skip: if labels: del (elem['concept']) x[key] = elem if key == 'economy': x[key]['aggregate'] = elem['id'] in aggs elif key == 'time' and numericTimeKeys and elem[ 'value'].isdigit(): x[key]['id'] = int(elem['value']) else: x[key] = elem['id'] if key == 'economy': x['aggregate'] = elem['id'] in aggs elif key == 'time' and numericTimeKeys and elem[ 'value'].isdigit(): x[key] = int(elem['value']) if not skip: yield x