diff --git a/tcmb/auth.py b/tcmb/auth.py index 230c5b2..7dbc246 100644 --- a/tcmb/auth.py +++ b/tcmb/auth.py @@ -33,7 +33,9 @@ def check_status(response): # Therefore the traceback is printed as well as the most # probable cause of the HTTPError: ApiKeyError print(err.with_traceback(None)) - raise ApiKeyError("API key is invalid.") from err + raise ApiKeyError( + "API key is invalid or wrong key. See error message for details." + ) from err else: try: response.json() diff --git a/tcmb/core.py b/tcmb/core.py index 19526bf..d1ad586 100644 --- a/tcmb/core.py +++ b/tcmb/core.py @@ -122,7 +122,9 @@ def read( # convert list to str seperated by "-" # as descibed in the api reference if isinstance(series, list): - series = "-".join(series) + series_str = "-".join(series) + else: + series_str = series # convert list to str seperated by "-" if isinstance(agg, list): @@ -135,7 +137,7 @@ def read( end = utils.standardize_date(end) params = { - "series": series, + "series": series_str, "startDate": start or "01-01-1970", "endDate": end or date.today().strftime("%d-%m-%Y"), "type": "json", # csv, xml, json @@ -156,7 +158,7 @@ def read( # convert response JSON to DataFrame # time series data is in the "items" - data = utils.to_dataframe(res.json()["items"]) + data = utils.to_dataframe(res.json()["items"], series=series) return data diff --git a/tcmb/utils.py b/tcmb/utils.py index 84e32da..6f6dc4b 100644 --- a/tcmb/utils.py +++ b/tcmb/utils.py @@ -10,6 +10,8 @@ import numpy as np import pandas as pd +from tcmb._data import fetch_dg_series_codes + def standardize_date(date_str: str) -> str: """Standardize date string format to output DD-MM-YYYY. @@ -45,14 +47,22 @@ def standardize_date(date_str: str) -> str: return datetime.strptime(date_str, date_format).strftime("%d-%m-%Y") -def to_dataframe(data: dict) -> pd.DataFrame: +def to_dataframe(data: dict, series: str | list) -> pd.DataFrame: """Convert data from the json response to pandas DataFrame.""" + if isinstance(series, str): + series = [series] + + # generate column names from series keys by replacing "." with "_" + # these columns will be selected as the value columns + # the columns other than date (Tarih) and value columns will be dropped + value_cols = [col.replace(".", "_") for col in series] + df = pd.DataFrame(data) # drop unused column - df = df.drop("UNIXTIME", axis=1) + df = df[["Tarih", *value_cols]] # set date as index - # TODO: check if "Tarih" always the first column - df = df.set_index(df.columns[0]) + # TODO: check if "Tarih" always the date column + df = df.set_index("Tarih") # detect date format if re.match(r"\d+-\d+-\d{4}", df.index[0]): @@ -63,6 +73,7 @@ def to_dataframe(data: dict) -> pd.DataFrame: date_format = "%Y-%m" elif re.match(r"\d{4}", df.index[0]): date_format = "%Y" + # convert date strings to datetime df.index = pd.to_datetime(df.index, format=date_format) @@ -128,8 +139,6 @@ def wildcard_search( dg_series = json.load(file) else: - from tcmb._data import fetch_dg_series_codes - dg_series = fetch_dg_series_codes() # merge series of all datagroups into one list diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..042962c --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,31 @@ +from tcmb import utils + +import pytest + + +test_date_data = [ + ("01-01-2024", "01-01-2024"), + ("17.12.2009", "17-12-2009"), + ("2011-06-18", "18-06-2011"), + ("2018.04.10", "10-04-2018"), +] + + +@pytest.mark.parametrize("date_str, expected", test_date_data) +def test_standardize_date(date_str, expected): + result = utils.standardize_date(date_str) + print(result) + assert result == expected + + +def test_wildcard_search(): + items_expected = [ + "TP.API.REP.TL.A12", + "TP.API.REP.TL.A23", + "TP.API.REP.TL.G1", + "TP.API.REP.TL.G1530", + "TP.API.REP.TL.G214", + ] + items = utils.wildcard_search("TP.API.REP.TL.*") + + assert all(item in items_expected for item in items)