Keep the market-hours database when a refresh returns malformed JSON

Offen
#709 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 2 Tagen

@pcbeingused333 arbeitet bereits daran.

Seit 04.11.2026.

  • #710 von @pcbeingused333 — offen

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
35/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Veraltet
Tech-Stack
python
Bereich
cli, databases, testing

Rechercherichtung

Read lean/components/cloud/data_downloader.py and lean/components/util/market_hours_database.py to trace the download, file replacement, refresh timestamp, and JSON reader behavior. Check the existing tests for these components, then add the described regression case with a valid cached database and malformed response. Done means invalid content leaves the prior database usable and refresh is recorded only after a successful update. An open linked pull request (#710) is already against this issue.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Problem

On master (d812d26), a successful HTTP response containing malformed JSON can overwrite a usable local market-hours database. Subsequent database reads fail instead of retaining the last valid data.

The path is:

  • DataDownloader.update_database_files() (lean/components/cloud/data_downloader.py:83-92) downloads the market-hours database and passes its bytes directly to _store_local_file.
  • DataClient.download_public_file() (lean/components/api/data_client.py:89-95) returns raw response content, without JSON validation.
  • _store_local_file() (lean/components/cloud/data_downloader.py:24-27) opens the existing file with wb+ and writes those bytes.
  • MarketHoursDatabase._get_all_entries() (lean/components/util/market_hours_database.py:63-69) only parses the JSON when it is later read.

The refresh timestamp is also recorded before the download/write (data_downloader.py:85), so a malformed successful response can leave the bad file in place until the next configured refresh interval.

Synthetic reproduction

With the CLI installed and initialized, this uses only a temporary file, not an actual data directory:

import json
import tempfile
from pathlib import Path
from lean.components.cloud.data_downloader import _store_local_file

with tempfile.TemporaryDirectory() as directory:
    cache = Path(directory) / "market-hours-database.json"
    previous = '{"entries": {}}'
    cache.write_text(previous, encoding="utf-8")

    # Bytes returned by a malformed HTTP 200 response.
    _store_local_file(b"not json", cache)
    print(cache.read_text(encoding="utf-8"))  # not json; valid data is lost
    json.loads(cache.read_text(encoding="utf-8"))  # JSONDecodeError

I verified the same result using the isolated _store_local_file function from master: the file becomes not json, and the next decode raises JSONDecodeError. This is a synthetic malformed response, not a report that the hosted database is currently malformed.

Suggested fix

Validate the downloaded market-hours content using the format accepted by its reader (including supported comments and the required entries structure) before replacing the local file. Write through a temporary file, preserve the existing file's access metadata, and replace only after validation and writing succeed. Record a successful refresh only after it completes. Add a regression test with a pre-existing valid database and a malformed successful response.

Vorherrschende Sprache
Python
Sterne
330
Forks
171
Ø Merge
2 T. 21 Std.
Gemergte PRs (30 T.)
18

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus QuantConnect/lean-cli

Alle Issues in QuantConnect/lean-cli

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.