laga
laga repairs malformed JSON and returns Python objects.
It is built for the real world: model output, hand-written config, copied snippets, and other almost-JSON text that is usually close enough to recover but not strict enough for json.loads.
Highlights
- Repairs common JSON mistakes such as trailing commas, missing commas, single quotes, unquoted keys, comments, fences, smart quotes, and truncated containers.
- Tries the standard library first, so valid JSON stays fast and strict.
- Keeps the public API small:
repair,repair_to_str,loads, andLagaError. - Ships with a CLI, JSONL support, type information, tests, docs, and CI.
Supported Versions
laga 0.1.6 supports Python 3.10 through 3.13.
Install
For normal use from PyPI:
python -m pip install laga
For local development from a checkout:
python -m pip install -e ".[dev]"
Quick Start
import laga
text = "{name: 'Ada', active: True, roles: ['admin', 'writer',],}"
data = laga.repair(text)
print(data)
print(laga.repair_to_str(text))
CLI
You can also use laga from the command line:
laga "{name: 'Ada', active: True, roles: ['admin',]}"
laga --strict '{"a": 1,}'
Use --strict when you want to reject ambiguous repairs instead of filling in gaps.
Use --pretty to format output for humans, --stdin to read from standard input, and --duplicate-keys error when duplicate keys should fail.
Use --input to read from a file, --output to write the repaired result back to disk, or --in-place to overwrite the input file directly.
Use --jsonl when each non-empty line is a separate JSON record and you want one repaired value per line.
laga --stdin --pretty
laga --input sample.txt --output fixed.json
laga --input sample.txt --in-place --pretty
laga --jsonl --stdin
laga --max-depth 64 --max-input-size 10000 --duplicate-keys error '{"a": 1}'
API
| Function | Returns | Description |
|---|---|---|
laga.repair(text, strict=False) |
Python object | Repairs malformed JSON and returns Python data. |
laga.repair_to_str(text, strict=False) |
str |
Repairs malformed JSON and returns normalized JSON text. |
laga.repair_jsonl(text, strict=False) |
list[object] |
Repairs newline-delimited JSON records and returns Python values. |
laga.repair_jsonl_to_str(text, strict=False) |
str |
Repairs newline-delimited JSON records and returns newline-delimited JSON text. |
laga.repair_file(path, strict=False) |
Python object | Reads a file and repairs its contents. |
laga.loads(text, strict=False) |
Python object | Alias for laga.repair. |
laga.LagaError |
Exception type | Raised when repair fails or input is unrecoverable. |
What It Repairs
| Rule | Before | After |
|---|---|---|
| Trailing comma | {"a": 1,} |
{"a":1} |
| Missing comma | {"a": 1 "b": 2} |
{"a":1,"b":2} |
| Single quotes | {'a': 'b'} |
{"a":"b"} |
| Unquoted keys | {name: "Ada"} |
{"name":"Ada"} |
| Python literals | {"ok": True, "none": None} |
{"ok":true,"none":null} |
| Comments | {"a": 1 // note\n} |
{"a":1} |
| Markdown fences | |
{"a":1} |
| Smart quotes | “a” |
"a" |
| Prose around JSON | Result: {"a":1} |
{"a":1} |
| Truncated structure | {"a": [1, 2 |
{"a":[1,2]} |
Strict Mode
strict=True is for validation workflows where you want laga to fail instead of guessing.
In strict mode, laga rejects ambiguous recoveries such as:
- missing commas between object members or array items
- unterminated objects or arrays
- other repairs that would require filling in structure the input did not clearly provide
Behavior Notes
json.loadsis still the best choice when you control the producer and the input is already valid JSON.- Duplicate keys use last-value-wins behavior, matching Python dict semantics.
- Use
duplicate_keys="error"when you want duplicate object members to fail instead of being merged. lagadoes not evaluate expressions or try to invent arbitrary JavaScript syntax.- The parser is intentionally conservative around malformed numbers and highly ambiguous text.
Quick Decision Guide
| Situation | Best choice |
|---|---|
| You control the producer and the input is valid JSON | json.loads |
| You have noisy LLM output, copied config, or prose around JSON | laga.repair |
| You have JSONL or line-delimited records to repair | laga.repair_jsonl |
| You need to repair a file directly | laga.repair_file |
| You want duplicate keys to fail | duplicate_keys="error" |
| You want a human-friendly result | repair_to_str(..., pretty=True) |
When To Use laga
Use laga when the input is noisy, user-facing, or generated by a model and you need a predictable repair step before parsing.
Use json.loads when correctness and strictness matter more than recovery.
Development
make install
make lint
make typecheck
make test
make build
Project Links
- Documentation: docs/index.md
- API details: docs/api.md
- Usage examples: docs/usage.md
- Contributing guide: CONTRIBUTING.md
Citation
If you use laga in academic work, research notes, or other formal writing, please cite the repository using the metadata in CITATION.cff.
Suggested citation format:
Laitinen-Fredriksson Lundström-Imanov, G. O. Y. (2026). laga (Version 0.1.6) [Computer software]. https://github.com/olaflaitinen/laga
Release files for laga 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| laga-0.1.6.tar.gz | 25.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| laga-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.6 kB
Release files / laga-0.1.6.tar.gz
| Download URL | laga-0.1.6.tar.gz |
|---|---|
| Size | 25.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1861980d9d58ae7dc86d8f10b6827bd19b33f34361a1af4aea344c71b5ac080b
|
|
BLAKE2b-256 checksum How to use checksums |
d2d24dec0d9aa95c0bf5c4d3234d5688d133c9798c8d8fc17d57d9f33cb1979a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency logRelease files / laga-0.1.6-py3-none-any.whl
| Download URL | laga-0.1.6-py3-none-any.whl |
|---|---|
| Size | 12.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
955e63a35d9d16cd2f4f48dd454b43f175a55dc7cc735e329b6a39f3b3002173
|
|
BLAKE2b-256 checksum How to use checksums |
3c2b2e6ee9f7202d430b558b3df3a867724d3e9554c43ca185ea258b862a54f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency log