Python Bindings¶
Vexy JSON provides comprehensive Python bindings that offer all the functionality of the Rust library with a familiar Python API. The bindings are designed to be both performant and easy to use.
Installation¶
pip install vexy_json
Basic Usage¶
Parsing JSON¶
import vexy_json
# Standard JSON parsing
data = vexy_json.loads('{"name": "John", "age": 30}')
print(data) # {'name': 'John', 'age': 30}
# Parse with forgiving features
data = vexy_json.loads('''
{
name: "John", // Unquoted keys and comments
age: 30, // Trailing comma is okay
}
''')
JSON Compatibility¶
The Vexy JSON Python bindings provide full compatibility with the standard json
module:
import vexy_json
# Drop-in replacement for json.loads()
data = vexy_json.loads('{"key": "value"}')
# All standard json functions are available
json_str = vexy_json.dumps(data)
json_str = vexy_json.dumps(data, indent=2)
# File operations
with open('data.json', 'r') as f:
data = vexy_json.load(f)
with open('output.json', 'w') as f:
vexy_json.dump(data, f, indent=2)
Advanced Parsing Options¶
Custom Parser Options¶
import vexy_json
# Parse with custom options
data = vexy_json.parse_with_options(
json_string,
allow_comments=True,
allow_trailing_commas=True,
allow_unquoted_keys=True,
allow_single_quotes=True,
implicit_top_level=True,
newline_as_comma=True,
max_depth=128,
enable_repair=True,
max_repairs=100,
fast_repair=False,
report_repairs=True
)
Validation¶
import vexy_json
# Check if JSON is valid
is_valid = vexy_json.is_valid('{"valid": true}')
print(is_valid) # True
is_valid = vexy_json.is_valid('invalid json')
print(is_valid) # False
Streaming Support¶
Streaming Parser with Context Manager¶
import vexy_json
# Parse large JSON files efficiently
with vexy_json.StreamingParser() as parser:
with open('large_file.json', 'r') as f:
for item in parser.parse_stream(f):
process(item)
NDJSON Support¶
import vexy_json
# Parse NDJSON (newline-delimited JSON)
with vexy_json.StreamingParser() as parser:
with open('data.ndjson', 'r') as f:
for item in parser.parse_lines(f):
process(item)
Custom Streaming Options¶
import vexy_json
# Create streaming parser with custom options
parser = vexy_json.StreamingParser(
allow_comments=True,
allow_trailing_commas=True,
enable_repair=True
)
with parser as p:
for item in p.parse_stream(file_handle):
process(item)
NumPy Integration¶
Direct Array Parsing¶
import vexy_json
import numpy as np
# Parse JSON array directly to NumPy array
arr = vexy_json.loads_numpy('[1, 2, 3, 4, 5]')
print(type(arr)) # <class 'numpy.ndarray'>
print(arr.dtype) # int64
# Specify dtype
arr = vexy_json.loads_numpy('[1.1, 2.2, 3.3]', dtype='float32')
print(arr.dtype) # float32
Zero-Copy Optimization¶
import vexy_json
# Optimized parsing for numeric data
arr = vexy_json.loads_numpy_zerocopy('[1, 2, 3, 4, 5]', dtype='int64')
# Uses zero-copy when possible for better performance
Mixed Data Types¶
import vexy_json
# Handle mixed arrays
arr = vexy_json.loads_numpy('[1, 2.5, 3, 4.7]')
print(arr.dtype) # float64 (automatically promoted)
# Non-numeric data falls back to object arrays
arr = vexy_json.loads_numpy('["a", "b", "c"]')
print(arr.dtype) # object
Pandas Integration¶
DataFrame Conversion¶
import vexy_json
import pandas as pd
# Parse JSON to DataFrame
json_data = '[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]'
df = vexy_json.loads_dataframe(json_data)
print(type(df)) # <class 'pandas.core.frame.DataFrame'>
# Specify orientation
df = vexy_json.loads_dataframe(json_data, orient='records')
Error Handling¶
Parse Errors¶
import vexy_json
try:
data = vexy_json.loads('invalid json')
except ValueError as e:
print(f"Parse error: {e}")
Repair Functionality¶
import vexy_json
# Automatic repair of common JSON issues
try:
data = vexy_json.loads('{"key": "value",}') # Trailing comma
print(data) # Successfully parsed
except ValueError as e:
print(f"Even repair failed: {e}")
Performance Optimization¶
Choosing the Right Function¶
import vexy_json
# For standard JSON, use loads() for compatibility
data = vexy_json.loads(standard_json)
# For forgiving JSON, use parse_with_options()
data = vexy_json.parse_with_options(
forgiving_json,
allow_comments=True,
allow_trailing_commas=True
)
# For numerical data, use NumPy integration
arr = vexy_json.loads_numpy(json_array)
# For tabular data, use pandas integration
df = vexy_json.loads_dataframe(json_records)
Memory Efficiency¶
import vexy_json
# Streaming for large files
with vexy_json.StreamingParser() as parser:
for item in parser.parse_stream(large_file):
# Process items one at a time
# Memory usage stays constant
process(item)
Type Hints¶
The Python bindings include comprehensive type hints:
from typing import Any, Dict, List, Optional, Union
import vexy_json
def process_json(json_str: str) -> Dict[str, Any]:
return vexy_json.loads(json_str)
def safe_parse(json_str: str) -> Optional[Dict[str, Any]]:
try:
return vexy_json.loads(json_str)
except ValueError:
return None
Best Practices¶
Error Handling¶
import vexy_json
def safe_parse_json(json_str: str, default=None):
"""Safely parse JSON with fallback."""
try:
return vexy_json.loads(json_str)
except ValueError as e:
print(f"JSON parse error: {e}")
return default
# Usage
data = safe_parse_json(user_input, default={})
Performance Tips¶
- Use appropriate functions: Choose
loads()
for standard JSON,parse_with_options()
for forgiving JSON - Streaming for large files: Use
StreamingParser
for files that don't fit in memory - NumPy integration: Use
loads_numpy()
for numeric arrays - Pandas integration: Use
loads_dataframe()
for tabular data - Validate when necessary: Use
is_valid()
to check JSON before parsing
Memory Management¶
import vexy_json
# For large datasets, prefer streaming
def process_large_json(filename):
with vexy_json.StreamingParser() as parser:
with open(filename, 'r') as f:
for item in parser.parse_stream(f):
yield process_item(item)
# This keeps memory usage constant regardless of file size
Integration Examples¶
With Requests¶
import requests
import vexy_json
response = requests.get('https://api.example.com/data')
data = vexy_json.loads(response.text)
With FastAPI¶
from fastapi import FastAPI
import vexy_json
app = FastAPI()
@app.post("/parse-json")
async def parse_json(content: str):
try:
data = vexy_json.loads(content)
return {"success": True, "data": data}
except ValueError as e:
return {"success": False, "error": str(e)}
With Django¶
from django.http import JsonResponse
import vexy_json
def parse_json_view(request):
try:
data = vexy_json.loads(request.body)
# Process data
return JsonResponse({"success": True})
except ValueError as e:
return JsonResponse({"error": str(e)}, status=400)
Migration from Standard JSON¶
Drop-in Replacement¶
# Before
import json
data = json.loads(json_string)
# After
import vexy_json
data = vexy_json.loads(json_string) # Same interface, more forgiving
Gradual Migration¶
import json
import vexy_json
def parse_json_fallback(json_str):
"""Try standard JSON first, fall back to Vexy JSON."""
try:
return json.loads(json_str)
except json.JSONDecodeError:
return vexy_json.loads(json_str) # More forgiving parsing
Advanced Features¶
Custom Serialization¶
import vexy_json
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
# Convert to dict first, then serialize
person = Person("John", 30)
json_str = vexy_json.dumps(person.__dict__)
Configuration Management¶
import vexy_json
# Parse configuration files with comments
config_str = '''
{
// Database configuration
"database": {
"host": "localhost",
"port": 5432, // Default PostgreSQL port
"name": "myapp",
},
// API settings
"api": {
"timeout": 30,
"retries": 3,
}
}
'''
config = vexy_json.loads(config_str)
This comprehensive Python API provides all the power of Vexy JSON with the familiar interface Python developers expect.