tgherzog / wbgapi

Python module that makes using the World Bank's API a lot easier and more intuitive.
MIT License
140 stars 31 forks source link

Receiving Data from World Bank DBS-Database #30

Closed Crefok closed 1 year ago

Crefok commented 1 year ago

Hey, I am trying to receive data from the DBS-Database of the Workbank via this API.

Here is a minimal Code Example:

import wbgapi as wb
import pandas as pd

code_to_dbid_mapping = pd.DataFrame(wb.source.list()).set_index("code")["databid"].to_dict()

df = wb.data.DataFrame(series="IC.BUS.EASE.DFRN.XQ.DB1719", 
              db=code_to_dbid_mapping["DBS"], 
              numericTimeKeys=True,
              skipBlanks=True,
              time=range(2010, datetime.datetime.now().year), 
              labels=False)

but the code doesn't run. It raises an "JSONDecodeError"

here is the complete strack trace:

---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
File ~/miniconda3/envs/esg/lib/python3.9/site-packages/requests/models.py:971, in Response.json(self, **kwargs)
    970 try:
--> 971     return complexjson.loads(self.text, **kwargs)
    972 except JSONDecodeError as e:
    973     # Catch JSON-related errors and raise as requests.JSONDecodeError
    974     # This aliases json.JSONDecodeError and simplejson.JSONDecodeError

File ~/miniconda3/envs/esg/lib/python3.9/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    343 if (cls is None and object_hook is None and
    344         parse_int is None and parse_float is None and
    345         parse_constant is None and object_pairs_hook is None and not kw):
--> 346     return _default_decoder.decode(s)
    347 if cls is None:

File ~/miniconda3/envs/esg/lib/python3.9/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
    333 """Return the Python representation of ``s`` (a ``str`` instance
    334 containing a JSON document).
    335 
    336 """
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338 end = _w(s, end).end()

File ~/miniconda3/envs/esg/lib/python3.9/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)
    354 except StopIteration as err:
--> 355     raise JSONDecodeError("Expecting value", s, err.value) from None
    356 return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

JSONDecodeError                           Traceback (most recent call last)
File ~/miniconda3/envs/esg/lib/python3.9/site-packages/wbgapi/__init__.py:405, in _queryAPI(url)
    404 try:
--> 405     result = response.json()
    406 except:

File ~/miniconda3/envs/esg/lib/python3.9/site-packages/requests/models.py:975, in Response.json(self, **kwargs)
    972 except JSONDecodeError as e:
    973     # Catch JSON-related errors and raise as requests.JSONDecodeError
    974     # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
--> 975     raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

APIError                                  Traceback (most recent call last)
Cell In [62], line 7
      2 import pandas as pd
      5 code_to_dbid_mapping = pd.DataFrame(wb.source.list()).set_index("code")["databid"].to_dict()
----> 7 df = wb.data.DataFrame(series="IC.BUS.EASE.DFRN.XQ.DB1719", 
      8               db=code_to_dbid_mapping["DBS"], 
      9               numericTimeKeys=True,
     10               skipBlanks=True,
     11               time=range(2010, datetime.datetime.now().year), 
     12               labels=False)

File ~/miniconda3/envs/esg/lib/python3.9/site-packages/wbgapi/data.py:254, in DataFrame(series, economy, time, index, columns, mrv, mrnev, skipBlanks, labels, skipAggs, numericTimeKeys, timeColumns, params, db, **dimensions)
    252 # set up the axes by looking at the index/column parameters
    253 concepts = ['economy','series','time']
--> 254 for k,v in w.source.concepts(db).items():
    255     if k not in concepts:
    256         concepts.insert(0, k)

File ~/miniconda3/envs/esg/lib/python3.9/site-packages/wbgapi/source.py:81, in concepts(db)
     79 url = 'sources/{}/concepts'.format(db)
     80 c = {}
---> 81 for row in w.fetch(url, concepts=True):
     82     key = urllib.parse.quote(row['id']).lower()
     83     if key in ['country', 'economy', 'admin%20region', 'states', 'provinces']:

File ~/miniconda3/envs/esg/lib/python3.9/site-packages/wbgapi/__init__.py:195, in fetch(url, params, concepts, lang)
    192 while totalRecords is None or recordsRead < totalRecords:
    194     url_ = '{}/{}/{}?{}'.format(endpoint, lang, url, urllib.parse.urlencode(params_))
--> 195     (hdr,result) = _queryAPI(url_)
    197     if totalRecords is None:
    198         totalRecords = int(hdr['total'])

File ~/miniconda3/envs/esg/lib/python3.9/site-packages/wbgapi/__init__.py:407, in _queryAPI(url)
    405     result = response.json()
    406 except:
--> 407     raise APIError(url, 'JSON decoding error')
    409 hdr = _responseHeader(url, result)
    410 if hdr.get('message'):

APIError: APIError: JSON decoding error (https://api.worldbank.org/v2/en/sources/3001/concepts?per_page=1000&page=1&format=json)

Can Someone help here?

Thanks an Regards.

Edit: Data from the WGI-Database results in the same Exception

tgherzog commented 1 year ago

databid is used internally. You want the id column: 1 for Doing Business, 3 for World Governance Indicators, etc.

db_mapping = {row['code']:row['id'] for row in wb.source.list()}

df = wb.data.DataFrame(series="IC.BUS.EASE.DFRN.XQ.DB1719", 
              db=db_mapping['DBS'], 
              numericTimeKeys=True,
              skipBlanks=True,
              time=range(2010, datetime.datetime.now().year), 
              labels=False)
Crefok commented 1 year ago

the db needs to get the id not the databid now its working