A library to parse and repair malformed JSON-like text.
Project description
JSON Rescue
Overview
JSON Rescue is a robust Python library designed to parse and repair malformed JSON-like text, specifically targeting common errors found in AI model responses that fail to return valid JSON. The library employs heuristics to identify, fix, and validate JSON structures against a provided schema, ensuring data consistency and correctness.
Features
- Bracket Matching and Extraction: Uses advanced regex patterns to identify JSON-like structures within a text, even when nested.
- Schema Validation: Ensures the parsed JSON adheres to a defined schema using a customizable
Schemaclass. - Error Recovery: Attempts to fix common JSON errors, including:
- Missing or unquoted keys.
- Unquoted or improperly formatted string values.
- Missing or extra brackets.
- Escaping illegal characters.
- Customizable Fixes: Implements modular methods for fixing specific JSON issues.
Installation
pip install jsonrescue
Usage
Example
from jsonrescue.custom_schema import Schema, SchemaType
from jsonrescue.parser import Parser
# Define a schema for validation
schema = Schema(
type=SchemaType.OBJECT,
properties={
'name': Schema(type=SchemaType.STRING),
'age': Schema(type=SchemaType.NUMBER),
'emails': Schema(type=SchemaType.ARRAY, items=Schema(type=SchemaType.STRING))
},
required=['name', 'age']
)
parser = Parser(schema)
malformed_json = """
{
name: John Doe,
age: 30,
emails: ['john@example.com']
}
"""
parsed_data = parser.rescue(malformed_json)
if parsed_data:
print("Valid JSON:", parsed_data)
else:
print("Failed to parse JSON")
Examples of Errors Handled
- Missing Quotes Around Keys or Values:
- Input:
{name: John Doe, age: 22} - Output:
{"name": "John Doe", "age": 22}
- Input:
- Additional Text Around Object:
- Input:
Here is your result:\n{name: John Doe, age: 22}\n\nThank you! - Output:
{"name": "John Doe", "age": 22}
- Input:
- Unescaped Quotes Within Values:
- Input:
{"name": "John "Deere" Doe", "age": 30} - Output:
{"name": "John \"Deere\" Doe", "age": 30}
- Input:
- Fixing Broken Endings - adds missing double-quotes as well as ending brackets:
- Input:
{"name": "Bob", "age": 35, "emails": ["bob@example.com - Output:
{"name": "Bob", "age": 35, "emails": ["bob@example.com"]}
- Input:
- Handling Multiple Objects in Text: - even when without commas seperating the objects
- Input:
{"name": "Dana", "age": 27}{"name": "Chris", "age": 35} - Output:
{"name": "Dana", "age": 27}(Picks first valid object parsed if schema was an object) or - Alternative Output:
[{"name": "Dana", "age": 27},{"name": "Chris", "age": 35}](if schema was an array or if no schema was provided)
- Input:
- Handling Arrays When Object Expected:
- Input:
[{"name": "Alice", "age": 28}] - Output:
{"name": "Alice", "age": 28}
- Input:
- Handling Object When Array Expected:
- Input:
{"name": "Alice", "age": 28} - Output:
[{"name": "Alice", "age": 28}]
- Input:
Key Components
Class: Parser
Initialization
Parser(schema: Schema)
- schema: An instance of the
Schemaclass defining the expected JSON structure. To parse the text for JSON without any expected structure, simply skip defining theSchema
Methods
-
rescue(text: str) -> Any- Attempts to parse the input text as JSON.
- Validates against the provided schema.
-
extract_json_candidates(text: str) -> List[str]- Extracts potential JSON substrings from the input text using a bracket-matching regex.
-
fix_json(json_str: str) -> str- Applies a sequence of fixes to a JSON string.
-
fix_keys(json_str: str) -> str- Quotes unquoted object keys.
-
fix_string_values(json_str: str) -> str- Quotes unquoted string values.
-
escape_illegal_characters(json_str: str) -> str- Escapes problematic characters like newlines, tabs, and unescaped quotes.
-
ensure_ending_brackets(json_str: str) -> str- Fixes mismatched or missing brackets.
-
insert_missing_commas(json_str: str) -> str- Insert commas between adjacent objects/arrays
Advanced Configuration
The library allows customization and extension by overriding its methods for specific JSON-repair scenarios. For example, you can add custom regex patterns or post-processing logic as needed.
Limitations
- The parser assumes input text contains at least one valid JSON-like structure. Extremely malformed input may result in parsing failures.
- It relies on heuristics to fix errors, which may not always produce the intended results.
Testing
The project includes a suite of unit tests to validate its functionality. To run the tests:
python -m unittest test.py
Example Test Cases
-
Proper JSON:
input_text = '{"name": "John Doe", "age": 30, "emails": ["john@example.com"]}' expected = {"name": "John Doe", "age": 30, "emails": ["john@example.com"]}
-
Missing Required Field:
input_text = '{"name": "Test", "emails": ["test@example.com"]}' output_text = None
-
Incomplete Brackets:
input_text = 'Start {"name": "Bob", "age": 35, "emails": ["bob@example.com"' expected = {"name": "Bob", "age": 35, "emails": ["bob@example.com"]}
Contributing
Contributions are welcome! Please fork the repository and submit a pull request with your changes.
License
This project is licensed under the MIT License.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jsonrescue-1.0.4.tar.gz.
File metadata
- Download URL: jsonrescue-1.0.4.tar.gz
- Upload date:
- Size: 8.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
260029a4d868dc1af9f35523ac5296b34fb5f5080386e351640a0b2895deb29d
|
|
| MD5 |
039bc3324db1b97b44d064ed00ddf9c9
|
|
| BLAKE2b-256 |
e2e93b90f07a4efcaf427c23333c9699b0fb3c404648676895b82fc8b35b9947
|
File details
Details for the file jsonrescue-1.0.4-py3-none-any.whl.
File metadata
- Download URL: jsonrescue-1.0.4-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d844a0f31b161b95f27dff1d5e1f4f00571cdbb11b98bd957a299004aee159e7
|
|
| MD5 |
0c2cfa3748ca0cbeeb73585c71d18770
|
|
| BLAKE2b-256 |
4a9b1ff06ee90218152924a6045858ccfa909345208c8ede4b4773227e6891f7
|