Skip to content

Instantly share code, notes, and snippets.

@kristovatlas
Last active December 30, 2025 04:00
Show Gist options
  • Select an option

  • Save kristovatlas/824d0d74ac169cfd7b8810bb27143324 to your computer and use it in GitHub Desktop.

Select an option

Save kristovatlas/824d0d74ac169cfd7b8810bb27143324 to your computer and use it in GitHub Desktop.
Prettify JSON-y looking things locally
import ast
import json
import sys
def parse_nested_json(obj):
"""Recursively parse any string values that are valid JSON into objects."""
if isinstance(obj, dict):
return {k: parse_nested_json(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [parse_nested_json(i) for i in obj]
elif isinstance(obj, str):
try:
parsed = json.loads(obj)
return parse_nested_json(parsed) # Recurse if nested
except json.JSONDecodeError:
return obj # Not JSON, leave as string
else:
return obj
def parse_relaxed_json(input_path, output_path=None, indent=4, sort_keys=False):
try:
with open(input_path, 'r') as f:
data_str = f.read()
data = ast.literal_eval(data_str) # Parses with single quotes allowed
# Recursively parse nested JSON strings
expanded_data = parse_nested_json(data)
pretty_json = json.dumps(expanded_data, indent=indent, sort_keys=sort_keys)
if output_path:
with open(output_path, 'w') as f:
f.write(pretty_json)
print(f"Prettified JSON saved to {output_path}")
else:
print(pretty_json)
except SyntaxError as e:
print(f"Error: Invalid syntax for literal eval - {e}")
except ValueError as e:
print(f"Error: Malformed data - {e}")
except FileNotFoundError:
print(f"Error: File '{input_path}' not found")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python parse_relaxed_json.py input.json [output.json]")
sys.exit(1)
input_path = sys.argv[1]
output_path = sys.argv[2] if len(sys.argv) > 2 else None
parse_relaxed_json(input_path, output_path)
import pprint
import importlib
import sys
def dynamic_eval(text):
"""
Dynamically evaluates the Python expression in the text, importing modules as needed.
WARNING: This uses eval, which can be dangerous if the text is not trusted.
Use only with text from reliable sources.
"""
# Start with full builtins; for safety, you could restrict them
globs = {'__builtins__': __builtins__}
max_attempts = 20 # Prevent infinite loops, adjust as needed
attempts = 0
while attempts < max_attempts:
try:
return eval(text, globs)
except NameError as e:
# Extract the missing name
import re
match = re.search(r"name '(\w+)' is not defined", str(e))
if match:
missing_name = match.group(1)
else:
raise
try:
module = importlib.import_module(missing_name)
globs[missing_name] = module
except ImportError:
raise ValueError(f"Cannot import {missing_name}. It may not be a standard module or requires installation.")
attempts += 1
raise ValueError("Max attempts reached. Possible cyclic dependencies or complex issues.")
def pretty_print_python_output_from_file(filename):
"""
Reads the printed Python text from a file, parses it using dynamic_eval, and pretty-prints it.
:param filename: The path to the file containing the output from print() in Python.
:return: Pretty-printed string or error message.
"""
try:
with open(filename, 'r', encoding='utf-8') as file:
text = file.read().strip()
except Exception as e:
return f"Error reading the file: {str(e)}"
try:
obj = dynamic_eval(text)
except Exception as e:
return f"Error parsing the text: {str(e)}"
# Pretty-print the object with indentation
return pprint.pformat(obj, indent=4, width=80)
# Example usage via command line
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python script.py input_file [output_file]")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
result = pretty_print_python_output_from_file(input_file)
if output_file:
try:
with open(output_file, 'w', encoding='utf-8') as f:
f.write(result + '\n')
except Exception as e:
print(f"Error writing to output file: {str(e)}")
else:
print(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment