Date: 11/16/2020
Updated: 9/26/2024
Data source
Developer Information
GitHub
For the first time in its almost half a century of existence, this year’s publication of the World Bank’s International Debt Statistics (IDS) added an additional dimension to the data – the creditor country. You can now see the public and publicly guaranteed sector debt of low- and middle-income countries owed to each creditor country, either official (multilateral or bilateral) or non-official (private creditor and bondholders), providing more detailed information on the borrower-lender relationship. This brief guides serves to introduce you to this new data breakdown and get you started in your own analysis.
IDS Dimensions:
- Country (debtor country)
- Series (Indicator, such as Total Debt Stock)
- Time
- Counterpart area (creditor country) <- the new addition (default or total is "World")
To understand how to view a full list of dimensions (and series definitions), please read Part 1 of our IDS API guides.
The following code and text will show step-by-step how to:
- Setup - getting your environment ready with the needed Python packages
- API Request - understanding the path and variables of the IDS API request
- Query data
1. Setup¶
To start, make sure you have the following packages installed on your machine. If you aren't familiar with how to install a Python package, visit each of the linked packages below for instructions.
- requests: Making HTTP requests in Python
- json: Interpreting json
- pandas: Data analysis
- plotly: Data visualization
Then, open up your preferred mode of writing Python. This could be in a Jupyter Notebook using Jupyter Lab, using a code editor (like Cursor or Visual Studio) + command line, or just from the command line.
# Import packages
import requests
import json
import pandas as pd
import plotly.express as px
import plotly.io as pio
pio.renderers.default = "notebook" # use "pio.renderers" to see the default renderer
2. API Request¶
In the previous guides, we used a Python package to wrap the API and present us with data. This time, in order to better understand API requests we will take a closer look at how each variable is presented in the URL.
Below is an example of the 4 dimensional API request:
Let's dissect the URL to understand each component:
- https://api.worldbank.org/v2: This beginning portion of the above URL is called the endpoint - the starting point of the API from where you're requesting data.
To get specific data, we use a "path variable." The path is the word before the forward slash and the variable is the word after it.
- sources/6: "sources" is the path and we select the variable "6," corresponding to the IDS database.
After selecting the API source for the IDS database, we specify each of the 4 IDS dimensions:
country/AGO: "country" is the debtor country and AGO (the ISO code for Angola) is our variable.
counterpart-area/701: "counterpart-area" is the new dimension! This is the creditor country, showing public and publically guaranteed debt. By choosing "701" (the code for Japan) we are selecting the variable Japan as the official or bilateral lender.
series/DT.DOD.BLAT.CD: "series" is the path for our indicator code. In this case, the indicator is "DT.DOD.BLAT.CD," the code for the bilateral public and publically guaranteed debt outstanding and disbursed in US dollars current (PPG, bilateral (DOD, current US$)).
time/all: the "time" path will show us the yearly data. By selecting the variable "all" we can get all years, including the NaN values.
3. Query¶
Below is a function that will take the parameters you set in the "Creditor," "Debtor," and "Series" variables to create an API request and create a neat table.
ENTER YOUR PARAMETERS HERE:
debtorCountry = "AGO"
creditorCountry = "701"
series = "DT.DOD.BLAT.CD"
time = "All"
The following code will use the entered parameters above to get the selected data from the World Bank API:
# Setting up the API URL
url = "https://api.worldbank.org/v2/sources/6/country/"
end = "?format=json&per_page=500"
path = url+debtorCountry+"/series/"+series+"/counterpart-area/"+creditorCountry+"/time/"+time+end
# Function that will parse through the JSON response and build the DataFrame
def getData(JSON):
# Create an empty DataFrame with specified columns
df = pd.DataFrame(columns=["year", "creditor", "debtor", "indicator", "data"])
# Loop through the JSON response
data_list = [] # Create a list to store rows
for i in range(0, listlen):
time = JSON["source"]["data"][i]["variable"][1]["value"]
num = JSON["source"]["data"][i]["value"]
# Create a row dictionary and append to the list
data_list.append({
"year": time,
"creditor": creditorCountry,
"debtor": debtorCountry,
"indicator": series,
"data": num
})
# Use pd.concat() instead of append to combine data
df = pd.concat([df, pd.DataFrame(data_list)], ignore_index=True)
return df
# Getting the data from the API
custom = requests.get(path)
customJSON = custom.json()
listlen = int(len(customJSON["source"]["data"]))
# Parse the JSON data and print the resulting DataFrame (excluding NaN values)
IDSdata = getData(customJSON).dropna()
print(IDSdata)
year creditor debtor indicator data 40 2010 701 AGO DT.DOD.BLAT.CD 0.0 41 2011 701 AGO DT.DOD.BLAT.CD 39462168.9 42 2012 701 AGO DT.DOD.BLAT.CD 163188908.1 43 2013 701 AGO DT.DOD.BLAT.CD 155071225.1 44 2014 701 AGO DT.DOD.BLAT.CD 631822127.3 45 2015 701 AGO DT.DOD.BLAT.CD 939776556.0 46 2016 701 AGO DT.DOD.BLAT.CD 900409328.8 47 2017 701 AGO DT.DOD.BLAT.CD 849192754.7 48 2018 701 AGO DT.DOD.BLAT.CD 767018346.2 49 2019 701 AGO DT.DOD.BLAT.CD 685156868.1 50 2020 701 AGO DT.DOD.BLAT.CD 683476988.6 51 2021 701 AGO DT.DOD.BLAT.CD 654977078.0 52 2022 701 AGO DT.DOD.BLAT.CD 499061959.9
Now that you have selected data, you can create a bar chart showing the increase in official bilateral PPG lending from Japan to Angola.
# Selecting the dataframe created above as the data source for the chart
source = IDSdata
# Plugging in the datasource, X and Y indicators, and the title for the chart
chart = px.bar(source,
x="year",
y="data",
title="Official bilateral PPG Lending from Japan to Angola (US$)")
chart.update_layout(
plot_bgcolor="white")
# Displaying the chart
chart