A comprehensive Python library for serializing and deserializing Python objects to and from JSON (dictionaries) with minimal code changes required.
81
Base classes and utilities for integrating JSON serialization directly into your Python classes. The JsonSerializable class provides a convenient way to add built-in JSON capabilities to your objects through inheritance.
class JsonSerializable:
"""
Base class that provides JSON serialization capabilities to any class that inherits from it.
Offers an alternative to using jsons.load and jsons.dump methods directly.
"""
@property
def json(self):
"""
Serialize this instance to a JSON-compatible dictionary.
Returns:
dict: JSON representation of this instance (equivalent to jsons.dump(self))
"""
@classmethod
def from_json(cls, json_obj, **kwargs):
"""
Deserialize a JSON object into an instance of this class.
Parameters:
- json_obj: JSON-compatible object (dict, list, etc.) to deserialize
- **kwargs: Additional arguments passed to the load function
Returns:
Instance of this class reconstructed from json_obj
Raises:
- DeserializationError: If json_obj cannot be deserialized to this class
"""
def dump(self, **kwargs):
"""
Serialize this instance (equivalent to json property but allows kwargs).
Parameters:
- **kwargs: Additional arguments passed to jsons.dump
Returns:
dict: JSON representation of this instance
"""
@classmethod
def load(cls, json_obj, **kwargs):
"""
Deserialize JSON object into instance (equivalent to from_json but allows kwargs).
Parameters:
- json_obj: JSON-compatible object to deserialize
- **kwargs: Additional arguments passed to jsons.load
Returns:
Instance of this class
"""class JsonSerializable:
@classmethod
def fork(cls, name=None):
"""
Create a 'fork' of JsonSerializable with separate serializer/deserializer configuration.
Parameters:
- name: Optional name for the new type (defaults to auto-generated)
Returns:
type: New JsonSerializable-based class with separate configuration
"""
@classmethod
def with_dump(cls, fork=False, **kwargs):
"""
Return a class based on JsonSerializable with dump method pre-configured with kwargs.
Parameters:
- fork: Bool determining if a new fork should be created
- **kwargs: Keyword arguments automatically passed to dump method
Returns:
type: Class with customized dump behavior
"""
@classmethod
def with_load(cls, fork=False, **kwargs):
"""
Return a class based on JsonSerializable with load method pre-configured with kwargs.
Parameters:
- fork: Bool determining if a new fork should be created
- **kwargs: Keyword arguments automatically passed to load method
Returns:
type: Class with customized load behavior
"""import jsons
from jsons import JsonSerializable
from typing import List
class Person(JsonSerializable):
def __init__(self, name: str, age: int, hobbies: List[str]):
self.name = name
self.age = age
self.hobbies = hobbies
class Company(JsonSerializable):
def __init__(self, name: str, employees: List[Person]):
self.name = name
self.employees = employees
# Create objects
employees = [
Person("Alice", 30, ["reading", "hiking"]),
Person("Bob", 25, ["gaming", "cooking"])
]
company = Company("Tech Corp", employees)
# Serialize using json property
company_dict = company.json
print(company_dict)
# {
# 'name': 'Tech Corp',
# 'employees': [
# {'name': 'Alice', 'age': 30, 'hobbies': ['reading', 'hiking']},
# {'name': 'Bob', 'age': 25, 'hobbies': ['gaming', 'cooking']}
# ]
# }
# Deserialize using from_json class method
company_restored = Company.from_json(company_dict)
print(company_restored.name) # "Tech Corp"
print(company_restored.employees[0].name) # "Alice"
print(company_restored.employees[1].hobbies[0]) # "gaming"import jsons
from jsons import JsonSerializable, KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE
# Create custom serializable with camelCase keys for JSON
CustomSerializable = JsonSerializable.with_dump(
key_transformer=KEY_TRANSFORMER_CAMELCASE
).with_load(
key_transformer=KEY_TRANSFORMER_SNAKECASE
)
class APIResponse(CustomSerializable):
def __init__(self, user_name: str, is_active: bool, last_login_date: str):
self.user_name = user_name
self.is_active = is_active
self.last_login_date = last_login_date
response = APIResponse("john_doe", True, "2023-12-01")
# Serializes with camelCase keys
json_response = response.json
print(json_response)
# {'userName': 'john_doe', 'isActive': True, 'lastLoginDate': '2023-12-01'}
# Can deserialize from camelCase JSON
camel_data = {'userName': 'jane_smith', 'isActive': False, 'lastLoginDate': '2023-11-15'}
response = APIResponse.from_json(camel_data)
print(response.user_name) # "jane_smith" (converted back to snake_case)import jsons
from jsons import JsonSerializable
# Create a fork with separate serializer configuration
CustomJsonSerializable = JsonSerializable.fork("CustomJSON")
# Configure the fork with custom serializers
def custom_string_serializer(s: str, **kwargs):
return s.upper() # All strings serialized in uppercase
jsons.set_serializer(custom_string_serializer, str, fork_inst=CustomJsonSerializable)
class RegularPerson(JsonSerializable):
def __init__(self, name: str):
self.name = name
class CustomPerson(CustomJsonSerializable):
def __init__(self, name: str):
self.name = name
regular = RegularPerson("Alice")
custom = CustomPerson("Bob")
print(regular.json) # {'name': 'Alice'}
print(custom.json) # {'name': 'BOB'} (uppercase due to custom serializer)import jsons
from jsons import JsonSerializable, Verbosity
# Create fork with verbose output
VerboseSerializable = JsonSerializable.with_dump(
fork=True, # Create new fork
verbosity=Verbosity.WITH_EVERYTHING
)
class DebugObject(VerboseSerializable):
def __init__(self, data: str):
self.data = data
debug_obj = DebugObject("test data")
verbose_json = debug_obj.json
print(verbose_json)
# Includes additional metadata like class info and dump timestampimport jsons
from jsons import JsonSerializable
class Product(JsonSerializable):
def __init__(self, name: str, price: float):
self.name = name
self.price = price
# JsonSerializable objects work seamlessly with regular jsons functions
product = Product("Laptop", 999.99)
# These are equivalent:
json1 = product.json
json2 = jsons.dump(product)
print(json1 == json2) # True
# Can also use jsons.load with JsonSerializable classes
product_data = {'name': 'Phone', 'price': 599.99}
product1 = Product.from_json(product_data)
product2 = jsons.load(product_data, Product)
print(product1.name == product2.name) # Trueimport jsons
from jsons import JsonSerializable, DeserializationError
class StrictUser(JsonSerializable):
def __init__(self, username: str, email: str):
self.username = username
self.email = email
# Handle deserialization errors
invalid_data = {'username': 'test'} # Missing required 'email' field
try:
user = StrictUser.from_json(invalid_data)
except DeserializationError as e:
print(f"Failed to deserialize: {e}")
print(f"Source data: {e.source}")
print(f"Target type: {e.target}")Install with Tessl CLI
npx tessl i tessl/pypi-jsonsdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10