Make orjson an optional dependency (closes #423)#454
Open
ShivamShrivastava18 wants to merge 1 commit into
Open
Make orjson an optional dependency (closes #423)#454ShivamShrivastava18 wants to merge 1 commit into
ShivamShrivastava18 wants to merge 1 commit into
Conversation
Move orjson from required dependencies to a 'orjson' optional extra, with a stdlib json fallback in _kaleido_tab/_tab.py and mocker/_utils.py. Users who want the fast path: pip install kaleido[orjson] Default install no longer pulls orjson, which fixes installation on Python 3.14t and in environments that prefer minimal dependencies.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #423.
Makes
orjsonan optional dependency with a stdlibjsonfallback, so users who can't (or don't want to) installorjson— e.g. on Python 3.14t, in minimal/locked-down environments, or just to reduce the dependency footprint — can install Kaleido without it.What changes for users
The default install no longer pulls
orjson. Anyone who wants the speed benefit opts in via the neworjsonextra.Files touched
src/py/pyproject.toml—orjson>=3.10.15moved fromdependenciesto[project.optional-dependencies]asorjson = ["orjson>=3.10.15"].src/py/kaleido/_kaleido_tab/_tab.py— adds_StdlibJSONEncoder(ajson.JSONEncodersubclass that mirrors_orjson_defaultby calling.tolist()on NumPy-like objects) and_serialize_spec(spec)(picks orjson when present, stdlib otherwise). The single call site in_calc_figbecomesspec_str = _serialize_spec(spec).src/py/kaleido/mocker/_utils.py— same import-guard pattern; load path now reads as bytes when orjson is available, as utf-8 text when it isn't. The yield loop is moved out of thewith path.open(...)block so it runs the same way under both branches (file is closed sooner; behavior visible to consumers is unchanged).How I verified
pip install -e .→ orjson absent →kaleido._kaleido_tab._tab.orjson is None→ stdlib path takenpip install -e ".[orjson]"→ orjson present → fast path takennp.arange,np.linspace,np.array(["a", ...]),np.int32(8)nested) showed both paths produce semantically equivalent JSON afterjson.loads: identical Python objects. Outputs differ only in whitespace (orjson is compact; stdlib uses default separators) — both are valid input for the JS-sideJSON.parse.ruff check— clean on all three filesruff format --check— cleantests/test_utils.py,tests/test_path_tools.py,tests/test_placeholder.py) pass. The browser-dependent tests intests/test_encoder_one_off.pyetc. couldn't be run locally without Chrome; full CI will exercise them.Notes for review
mocker/_utils.py: thefor f, w, h, s in itertools.product(...)yield loop was originally nested insidewith path.open(...), so the JSON file stayed open during iteration. The new structure closes the file immediately after parsing and then iterates. The yielded data is identical; this is purely a resource-management improvement.JSONEncodercannot matchorjson's exact byte-level output (noOPT_SERIALIZE_NUMPY, different whitespace). The downstream consumer isJSON.parse(specStr)on the JS side, which is whitespace-tolerant — semantic equivalence is what matters and is verified.AI disclosure
This change was authored with Claude Code assistance. I read the full diff, ran the verification steps above myself, and can explain every change.