safe-json
Extract and safely repair JSON payloads from messy, conversational Large Language Model (LLM) responses.
LLMs are notoriously bad at outputting strictly raw JSON. Even when instructed otherwise, they often bury payloads inside markdown code fences, inject conversational preambles/postambles, mix up single and double quotes, or append invalid trailing commas.
safe-json provides a fast, lightweight, and zero-dependency toolkit to gracefully locate, conservatively repair, and safely parse these structures back into standard Python objects.
Key Features
- Smart Extraction — Prefers explicit markdown code blocks, but falls back to finding the outermost balanced structural bounds (
{...}or[...]) if the model didn't format it cleanly. - Conservative Multi-pass Repairs — Safely repairs systemic structural errors (like JavaScript/Python style trailing commas or unescaped single quotes) only if initial strict JSON validation fails.
- Zero Dependencies — Built completely around the native standard library (
jsonandre), adding negligible runtime footprint to web apps or edge servers. - Production Resilient — Includes a
None-safe fallback engine as well as deterministic error tracking featuring full raw string payload context capture.
Installation
Install using pip from PyPI:
pip install safe-json
Quick Start
from safe_json import extract, extract_or_raise, SafeJSONError
# 1. Non-raising extraction (returns None on absolute failure)
data = extract("Some chatbot text... ```json\n{'id': 1,}\n```")
# -> {'id': 1}
# 2. Strict raising extraction (with context payload protection)
try:
data = extract_or_raise("Sorry, I cannot process your request.")
except SafeJSONError as e:
print(f"Extraction failed! Raw output was: {e.original}")
Practical Usage Examples
1. Stripping Markdown & Conversational Text
LLMs frequently sandwich JSON payloads between conversational text and markdown formatting code blocks. safe-json extracts the underlying collection reliably.
from safe_json import extract
llm_output = """
Certainly! Here is the metadata blueprint you requested for your system:
```json
{
"project_name": "Phoenix Alpha",
"tags": ["cloud", "serverless"]
}
Please let me know if you need changes to this setup! """
blueprint = extract(llm_output) print(blueprint["project_name"]) # Output: Phoenix Alpha
### 2. Auto-Repairing Common Syntax Hallucinations
When generative token limits are hit or models act lazily, they routinely break compliance rules by leaving Python dict trailing commas or applying weak single quotes.
```python
from safe_json import extract
# Example A: Messy trailing commas inside arrays and objects
bad_commas = '{"items": [10, 20, 30,], "status": "active",}'
print(extract(bad_commas))
# Output: {'items': [10, 20, 30], 'status': 'active'}
# Example B: Out-of-spec single quote string literals
bad_quotes = "{'error_code': 'UNAUTHORIZED', 'retry': true}"
print(extract(bad_quotes))
# Output: {'error_code': 'UNAUTHORIZED', 'retry': True}
3. Real-World Integration (e.g., OpenAI Chat Completion)
Easily plug safe-json into your standard agent loops or LLM extraction flows to act as your sanitisation layer.
import os
from openai import OpenAI
from safe_json import extract_or_raise
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Output user schema metrics in JSON."}]
)
raw_content = response.choices.message.content
# Guard the application logic with robust parsing
try:
metrics = extract_or_raise(raw_content)
print(f"Active Users: {metrics['active_users']}")
except Exception as err:
print(f"Failed to safely structuralise agent response: {err}")
4. Running in Strict Mode (Disabling Repairs)
If you are leveraging strict model structured outputs (e.g., JSON Mode) and want to intentionally fail if the string deviates from JSON standards, you can disable the correction heuristics.
from safe_json import extract
text_with_syntax_errors = "```json\n{'id': 101,}\n```"
# Passing repair=False forces regular strict standard parsing constraints
strict_data = extract(text_with_syntax_errors, repair=False)
print(strict_data) # Output: None
API Architecture Reference
extract(text: str, repair: bool = True) -> Any | None
Attempts to match structural boundaries and convert content into native collection formats.
text: The raw string target input to search across.repair: IfTrue, runs deep string cleanup iterations (trailing commas, single quote modifications) on validation failures.- Returns: Parsed Python
dict,list, or primitive scalars if valid; otherwise returnsNone.
extract_or_raise(text: str, repair: bool = True) -> Any
Works identically to extract, but instead of yielding None on unresolvable payloads, throws a traceable SafeJSONError.
SafeJSONError
Custom wrapper exception raised by failures.
.original: A property attribute exposing the exact, complete input string passed into the function, enabling system fallback logs to save the unparsed data for debugging or telemetry.
Performance & Extraction Design Matrix
The extraction parsing pipeline operates via structural multi-pass analysis:
Metadata
Release files for machine-learning-safe-json 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| machine_learning_safe_json-1.0.0.tar.gz | 7.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| machine_learning_safe_json-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.2 kB
Release files / machine_learning_safe_json-1.0.0.tar.gz
| Download URL | machine_learning_safe_json-1.0.0.tar.gz |
|---|---|
| Size | 7.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
abed485d7954e861af5368e48c80ec0bc5597e43d37c4d21018624523e003e89
|
|
BLAKE2b-256 checksum How to use checksums |
bad0ff213f4f04711386876d11a13b342946a0ec778db50a2d257c821d8b9b69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / machine_learning_safe_json-1.0.0-py3-none-any.whl
| Download URL | machine_learning_safe_json-1.0.0-py3-none-any.whl |
|---|---|
| Size | 6.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
030277d1633853e65795cf18a765f6ed293dc80634667395e61db49e15001698
|
|
BLAKE2b-256 checksum How to use checksums |
eeee4e0cf9550d04c47af2de5b409475de10d50b69822f7332f761aac7a7ff87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for machine-learning-safe-json 1.0.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.