Skip to content

Commit ad1def7

Browse files
authored
Force refresh modules JSON when --update is passed (#642)
* Add force refresh of modules JSON on --update flag * Move modules JSON download to reusable function * Minor fix
1 parent 986563f commit ad1def7

4 files changed

Lines changed: 53 additions & 11 deletions

File tree

lean/click.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ def invoke(self, ctx: Context):
274274
update_manager = container.update_manager
275275
update_manager.show_announcements()
276276

277+
if ctx.params.get("update", False):
278+
update_manager.force_refresh_modules_json()
279+
277280
result = super().invoke(ctx)
278281

279282
update_manager.warn_if_cli_outdated()

lean/components/util/update_manager.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@ def show_announcements(self) -> None:
162162

163163
self._logger.info(Panel.fit(table, title="Announcements", box=box.SQUARE))
164164

165+
def force_refresh_modules_json(self) -> None:
166+
"""Forces a re-download of the modules JSON file, bypassing the 24-hour cache interval."""
167+
from lean.models import _download_modules_json
168+
try:
169+
_download_modules_json()
170+
except Exception:
171+
# No need to do anything if file isn't available
172+
pass
173+
165174
def _should_check_for_updates(self, key: str, interval_hours: int) -> bool:
166175
"""Returns whether an update check should be performed.
167176

lean/models/__init__.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,26 @@
2323

2424
# check if new file is available online
2525
url = f"https://cdn.quantconnect.com/cli/{file_name}"
26+
27+
28+
def _download_modules_json() -> None:
29+
"""Downloads the modules JSON file from the CDN and saves it to disk."""
30+
from requests import get
31+
res = get(url, timeout=5)
32+
if res.ok:
33+
from json import dump
34+
file_path.parent.mkdir(parents=True, exist_ok=True)
35+
with open(file_path, 'w', encoding='utf-8') as f:
36+
dump(res.json(), f, ensure_ascii=False, indent=4)
37+
else:
38+
res.raise_for_status()
39+
40+
2641
error = None
2742
try:
2843
# fetch if file not available or fetched before 1 day
2944
if not path.exists(file_path) or (time() - path.getmtime(file_path) > 86400):
30-
from requests import get
31-
res = get(url, timeout=5)
32-
if res.ok:
33-
new_content = res.json()
34-
from json import dump
35-
# create parents if not exists
36-
file_path.parent.mkdir(parents=True, exist_ok=True)
37-
with open(file_path, 'w', encoding='utf-8') as f:
38-
dump(new_content, f, ensure_ascii=False, indent=4)
39-
else:
40-
res.raise_for_status()
45+
_download_modules_json()
4146
except Exception as e:
4247
# No need to do anything if file isn't available
4348
error = str(e)

tests/components/util/test_update_manager.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,31 @@ def test_show_announcements_does_nothing_when_latest_announcements_shown_before(
277277
logger.info.assert_not_called()
278278

279279

280+
def test_force_refresh_modules_json_downloads_file(requests_mock: RequestsMock) -> None:
281+
from lean.models import url as modules_url, file_path as modules_file_path
282+
modules_json = {"modules": {"SomeModule": {"version": "1.0"}}}
283+
requests_mock.add(requests_mock.GET, modules_url, json=modules_json)
284+
285+
logger, storage, docker_manager, update_manager = create_objects()
286+
287+
update_manager.force_refresh_modules_json()
288+
289+
assert modules_file_path.is_file()
290+
with open(modules_file_path) as f:
291+
assert json.load(f) == modules_json
292+
293+
294+
def test_force_refresh_modules_json_does_nothing_when_offline(requests_mock: RequestsMock) -> None:
295+
from lean.models import url as modules_url
296+
from requests.exceptions import ConnectionError as RequestsConnectionError
297+
requests_mock.add(requests_mock.GET, modules_url, body=RequestsConnectionError())
298+
299+
logger, storage, docker_manager, update_manager = create_objects()
300+
301+
# Should not raise
302+
update_manager.force_refresh_modules_json()
303+
304+
280305
def test_show_announcements_does_nothing_when_there_are_no_announcements(requests_mock: RequestsMock) -> None:
281306
requests_mock.add(requests_mock.GET,
282307
"https://raw.githubusercontent.com/QuantConnect/lean-cli/master/announcements.json",

0 commit comments

Comments
 (0)