Skip to content

Commit 71aabba

Browse files
wilsonfreitasclaude
andcommitted
Improve currency module cache: rename CACHE, add clear_cache() (Phase 7.2)
- Rename module-level CACHE to _CACHE (private by convention) - Add public clear_cache() function that empties _CACHE; documented with rationale (avoid redundant HTTP requests within a session) - Add caching Notes section to currency.get() docstring pointing to clear_cache() - Update tests/conftest.py autouse fixture to call currency.clear_cache() instead of accessing _CACHE directly - Add test_clear_cache() verifying that clear_cache() empties the cache and that subsequent calls re-populate it Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent db84d6b commit 71aabba

3 files changed

Lines changed: 44 additions & 9 deletions

File tree

bcb/currency.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,24 @@ def _currency_url(currency_id: int, start_date: DateInput, end_date: DateInput)
2727
)
2828

2929

30-
CACHE: dict[str, pd.DataFrame] = dict()
30+
_CACHE: dict[str, pd.DataFrame] = dict()
31+
32+
33+
def clear_cache() -> None:
34+
"""Clear the module-level session cache.
35+
36+
:func:`get` and :func:`get_currency_list` cache the currency ID list and
37+
the full currency master table for the duration of the Python session so
38+
that repeated calls do not make redundant HTTP requests. Call this
39+
function to force a fresh fetch on the next request (useful in tests or
40+
long-running scripts where the master data may have changed).
41+
"""
42+
_CACHE.clear()
3143

3244

3345
def _currency_id_list() -> pd.DataFrame:
34-
if CACHE.get("TEMP_CURRENCY_ID_LIST") is not None:
35-
return CACHE.get("TEMP_CURRENCY_ID_LIST")
46+
if _CACHE.get("TEMP_CURRENCY_ID_LIST") is not None:
47+
return _CACHE.get("TEMP_CURRENCY_ID_LIST")
3648
else:
3749
url1 = (
3850
"https://ptax.bcb.gov.br/ptax_internet/consultaBoletim.do?"
@@ -48,7 +60,7 @@ def _currency_id_list() -> pd.DataFrame:
4860
x = [(elm.text, elm.get("value")) for elm in doc.xpath(xpath)]
4961
df = pd.DataFrame(x, columns=["name", "id"])
5062
df["id"] = df["id"].astype("int32")
51-
CACHE["TEMP_CURRENCY_ID_LIST"] = df
63+
_CACHE["TEMP_CURRENCY_ID_LIST"] = df
5264
return df
5365

5466

@@ -76,8 +88,8 @@ def get_currency_list() -> pd.DataFrame:
7688
DataFrame :
7789
Tabela com a listagem de moedas disponíveis.
7890
"""
79-
if CACHE.get("TEMP_FILE_CURRENCY_LIST") is not None:
80-
return CACHE.get("TEMP_FILE_CURRENCY_LIST")
91+
if _CACHE.get("TEMP_FILE_CURRENCY_LIST") is not None:
92+
return _CACHE.get("TEMP_FILE_CURRENCY_LIST")
8193
else:
8294
res = _get_valid_currency_list(date.today())
8395
df = pd.read_csv(StringIO(res.text), delimiter=";")
@@ -95,7 +107,7 @@ def get_currency_list() -> pd.DataFrame:
95107
df["country_code"] = df["country_code"].astype("int32")
96108
df["code"] = df["code"].astype("int32")
97109
df["symbol"] = df["symbol"].str.strip()
98-
CACHE["TEMP_FILE_CURRENCY_LIST"] = df
110+
_CACHE["TEMP_FILE_CURRENCY_LIST"] = df
99111
return df
100112

101113

@@ -180,6 +192,13 @@ def get(
180192
Returns
181193
-------
182194
195+
Notes
196+
-----
197+
The currency ID list and the master currency table are cached in memory
198+
for the lifetime of the Python session so that multiple calls to
199+
:func:`get` do not repeat the same HTTP requests. Use
200+
:func:`clear_cache` to invalidate the cache when fresh data is needed.
201+
183202
DataFrame :
184203
Série temporal com cotações diárias das moedas solicitadas.
185204
"""

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@
8383
@pytest.fixture(autouse=True)
8484
def clear_currency_cache():
8585
"""Clear module-level currency cache before and after each test."""
86-
currency.CACHE.clear()
86+
currency.clear_cache()
8787
yield
88-
currency.CACHE.clear()
88+
currency.clear_cache()

tests/test_currency.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ def test_currency_id_list_cached(httpx_mock):
6565
assert df1 is df2
6666

6767

68+
def test_clear_cache(httpx_mock):
69+
# Populate the cache with one call
70+
add_id_list_mock(httpx_mock)
71+
currency._currency_id_list()
72+
assert currency._CACHE # cache is non-empty
73+
74+
# clear_cache() empties it
75+
currency.clear_cache()
76+
assert not currency._CACHE
77+
78+
# A subsequent call re-fetches and re-populates
79+
add_id_list_mock(httpx_mock)
80+
currency._currency_id_list()
81+
assert currency._CACHE
82+
83+
6884
# ---------------------------------------------------------------------------
6985
# get_currency_list
7086
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)