-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
7 sdr data #8
base: main
Are you sure you want to change the base?
7 sdr data #8
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8 +/- ##
==========================================
+ Coverage 90.71% 93.75% +3.03%
==========================================
Files 6 11 +5
Lines 183 320 +137
==========================================
+ Hits 166 300 +134
- Misses 17 20 +3 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks Luca! A few comments and requests throughout, mainly seeking to improve readability.
if unit_basis == "USD": | ||
col_val = "U.S.$1.00 = SDR" | ||
elif unit_basis == "SDR": | ||
col_val = "SDR1 = US$" | ||
else: | ||
raise ValueError("unit_basis must be either 'SDR' or 'USD'") | ||
|
||
df = df.iloc[:, 0].str.split("\t", expand=True) | ||
df.columns = df.iloc[0] | ||
df = df.iloc[1:] | ||
|
||
exchange_series = ( | ||
df.loc[lambda d: d["Report date"] == col_val].iloc[:, 1].reset_index(drop=True) | ||
) | ||
|
||
dates_series = ( | ||
df.dropna(subset=df.columns[3]) | ||
.iloc[:, 0] | ||
.drop_duplicates() | ||
.reset_index(drop=True) | ||
) | ||
|
||
return pd.DataFrame( | ||
{"date": dates_series, "exchange_rate": exchange_series} | ||
).assign( | ||
date=lambda d: pd.to_datetime(d.date), | ||
exchange_rate=lambda d: pd.to_numeric(d.exchange_rate, errors="coerce"), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does quite a bit without much documentation. It may be better to split some of this (to make it easier to test) and so the different steps are clearer.
|
||
|
||
@lru_cache | ||
def get_data(year: int, month: int): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that there are multiple functions that get data, it would be useful to give this a more meaningful name like get_holdings_and_allocations_data
BASE_URL = "https://www.imf.org/external/np/fin/data/rms_sdrv.aspx" | ||
|
||
|
||
def read_data(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the different functions that get or read data, it would be good to give this a more meaningful name that hints at what data it gets (and in this case it gets rather than reads, so get_exchange_rates_data
)
BASE_URL: str = "https://www.imf.org/external/np/fin/data/sdr_ir.aspx" | ||
|
||
|
||
def read_data(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as for other get/read data, a more meaningful name may help.
) | ||
|
||
|
||
def _format_data(df: pd.DataFrame) -> pd.DataFrame: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this formats and filters. It would help to split in two. Also because clean data does quite a bit - and this one also deals with cleaning)
tests/test_utils.py
Outdated
def test_make_request(): | ||
"""Test make_request""" | ||
|
||
# test successful request | ||
with patch("requests.get") as mock_get: | ||
mock_get.return_value.status_code = 200 | ||
response = utils.make_request(TEST_URL) | ||
assert response == mock_get.return_value | ||
|
||
# test failed request | ||
with patch("requests.get") as mock_get: | ||
mock_get.side_effect = requests.exceptions.RequestException | ||
with pytest.raises(ConnectionError, match="Could not connect to"): | ||
utils.make_request(TEST_URL) | ||
|
||
# test when status code is not 200 | ||
with patch("requests.get") as mock_get: | ||
mock_get.return_value.status_code = 404 | ||
with pytest.raises(ConnectionError, match="Could not connect to"): | ||
utils.make_request(TEST_URL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not convinced of the value of this type of test. You are basically testing requests
functionality, rather than anything about the logic of this package. I'd remove.
@mharoruiz FYI |
This pull request introduces a new module for reading Special Drawing Rights (SDR) data from the IMF, along with utility functions and tests. The most important changes include the creation of several new modules for fetching and processing SDR data, the addition of utility functions, and the restructuring of existing code to use these new utilities.
New SDR modules:
src/imf_reader/sdr/__init__.py
: Added a new module that provides functions for fetching SDR allocations, holdings, interest rates, and exchange rates.src/imf_reader/sdr/read_announcements.py
: Added functions to fetch SDR allocations and holdings data, including utility functions for reading and cleaning data.src/imf_reader/sdr/read_exchange_rate.py
: Added functions to fetch and parse SDR exchange rate data, with support for different unit bases.src/imf_reader/sdr/read_interest_rate.py
: Added functions to fetch and clean SDR interest rate data from the IMF website.Utility functions:
src/imf_reader/utils.py
: Added a utility functionmake_request
to handle HTTP requests and raise appropriate errors.Code restructuring:
src/imf_reader/weo/scraper.py
: Removed the localmake_request
function and replaced it with the new utility function fromutils.py
.Tests:
tests/test_utils.py
: Added tests for the new utility functionmake_request
to ensure it handles various scenarios correctly.tests/test_weo/test_scraper.py
: Removed tests for the localmake_request
function since it has been replaced by the utility function.Tests for SDR modules still need to be added