Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lean/click.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ def invoke(self, ctx: Context):
update_manager = container.update_manager
update_manager.show_announcements()

if ctx.params.get("update", False):
update_manager.force_refresh_modules_json()

result = super().invoke(ctx)

update_manager.warn_if_cli_outdated()
Expand Down
9 changes: 9 additions & 0 deletions lean/components/util/update_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ def show_announcements(self) -> None:

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

def force_refresh_modules_json(self) -> None:
"""Forces a re-download of the modules JSON file, bypassing the 24-hour cache interval."""
from lean.models import _download_modules_json
try:
_download_modules_json()
except Exception:
# No need to do anything if file isn't available
pass

def _should_check_for_updates(self, key: str, interval_hours: int) -> bool:
"""Returns whether an update check should be performed.

Expand Down
27 changes: 16 additions & 11 deletions lean/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,26 @@

# check if new file is available online
url = f"https://cdn.quantconnect.com/cli/{file_name}"


def _download_modules_json() -> None:
"""Downloads the modules JSON file from the CDN and saves it to disk."""
from requests import get
from json import dump
res = get(url, timeout=5)
if res.ok:
file_path.parent.mkdir(parents=True, exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
dump(res.json(), f, ensure_ascii=False, indent=4)
else:
res.raise_for_status()


error = None
try:
# fetch if file not available or fetched before 1 day
if not path.exists(file_path) or (time() - path.getmtime(file_path) > 86400):
from requests import get
res = get(url, timeout=5)
if res.ok:
new_content = res.json()
from json import dump
# create parents if not exists
file_path.parent.mkdir(parents=True, exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
dump(new_content, f, ensure_ascii=False, indent=4)
else:
res.raise_for_status()
_download_modules_json()
except Exception as e:
# No need to do anything if file isn't available
error = str(e)
Expand Down
25 changes: 25 additions & 0 deletions tests/components/util/test_update_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,31 @@ def test_show_announcements_does_nothing_when_latest_announcements_shown_before(
logger.info.assert_not_called()


def test_force_refresh_modules_json_downloads_file(requests_mock: RequestsMock) -> None:
from lean.models import url as modules_url, file_path as modules_file_path
modules_json = {"modules": {"SomeModule": {"version": "1.0"}}}
requests_mock.add(requests_mock.GET, modules_url, json=modules_json)

logger, storage, docker_manager, update_manager = create_objects()

update_manager.force_refresh_modules_json()

assert modules_file_path.is_file()
with open(modules_file_path) as f:
assert json.load(f) == modules_json


def test_force_refresh_modules_json_does_nothing_when_offline(requests_mock: RequestsMock) -> None:
from lean.models import url as modules_url
from requests.exceptions import ConnectionError as RequestsConnectionError
requests_mock.add(requests_mock.GET, modules_url, body=RequestsConnectionError())

logger, storage, docker_manager, update_manager = create_objects()

# Should not raise
update_manager.force_refresh_modules_json()


def test_show_announcements_does_nothing_when_there_are_no_announcements(requests_mock: RequestsMock) -> None:
requests_mock.add(requests_mock.GET,
"https://raw.githubusercontent.com/QuantConnect/lean-cli/master/announcements.json",
Expand Down
Loading