CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jsons

A comprehensive Python library for serializing and deserializing Python objects to and from JSON (dictionaries) with minimal code changes required.

81

1.65x
Overview
Eval results
Files

key-transformation.mddocs/

Key Transformation

Utilities for transforming dictionary keys between different naming conventions. The jsons library provides built-in functions to convert keys between camelCase, snake_case, PascalCase, and lisp-case formats, which is especially useful for API integration and cross-platform data exchange.

Capabilities

Case Transformation Functions

def camelcase(str_):
    """
    Transform string to camelCase format.
    
    Parameters:
    - str_: String to be transformed
    
    Returns:
    str: String in camelCase format (first letter lowercase, subsequent words capitalized)
    
    Examples:
    - 'hello_world' -> 'helloWorld'
    - 'user-name' -> 'userName' 
    - 'API_KEY' -> 'apiKey'
    """

def snakecase(str_):
    """
    Transform string to snake_case format.
    
    Parameters:
    - str_: String to be transformed
    
    Returns:
    str: String in snake_case format (all lowercase with underscores)
    
    Examples:
    - 'helloWorld' -> 'hello_world'
    - 'UserName' -> 'user_name'
    - 'API-Key' -> 'api_key'
    """

def pascalcase(str_):
    """
    Transform string to PascalCase format.
    
    Parameters:
    - str_: String to be transformed
    
    Returns:
    str: String in PascalCase format (first letter uppercase, subsequent words capitalized)
    
    Examples:
    - 'hello_world' -> 'HelloWorld'
    - 'user-name' -> 'UserName'
    - 'api_key' -> 'ApiKey'
    """

def lispcase(str_):
    """
    Transform string to lisp-case format.
    
    Parameters:
    - str_: String to be transformed
    
    Returns:
    str: String in lisp-case format (all lowercase with hyphens)
    
    Examples:
    - 'helloWorld' -> 'hello-world'
    - 'UserName' -> 'user-name'
    - 'api_key' -> 'api-key'
    """

Key Transformer Constants

# Pre-defined constants for use with dump/load functions
KEY_TRANSFORMER_SNAKECASE = snakecase
KEY_TRANSFORMER_CAMELCASE = camelcase  
KEY_TRANSFORMER_PASCALCASE = pascalcase
KEY_TRANSFORMER_LISPCASE = lispcase

Usage Examples

Basic Key Transformation

import jsons
from jsons import camelcase, snakecase, pascalcase, lispcase

# Transform individual strings
original = "user_profile_data"

print(camelcase(original))   # 'userProfileData'
print(snakecase(original))   # 'user_profile_data' (no change)
print(pascalcase(original))  # 'UserProfileData'
print(lispcase(original))    # 'user-profile-data'

# Transform from camelCase
camel_string = "firstName"
print(snakecase(camel_string))   # 'first_name'
print(pascalcase(camel_string))  # 'FirstName'
print(lispcase(camel_string))    # 'first-name'

# Transform with hyphens and mixed formats
mixed_string = "API-Response-Data"
print(camelcase(mixed_string))   # 'apiResponseData'
print(snakecase(mixed_string))   # 'api_response_data'
print(pascalcase(mixed_string))  # 'ApiResponseData'

Key Transformation in Serialization

import jsons
from jsons import KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE
from dataclasses import dataclass

@dataclass
class UserProfile:
    first_name: str
    last_name: str
    email_address: str
    phone_number: str
    is_active: bool

user = UserProfile(
    first_name="John",
    last_name="Doe", 
    email_address="john.doe@example.com",
    phone_number="+1-555-0100",
    is_active=True
)

# Serialize with camelCase keys
camel_json = jsons.dump(user, key_transformer=KEY_TRANSFORMER_CAMELCASE)
print(camel_json)
# {
#   'firstName': 'John',
#   'lastName': 'Doe',
#   'emailAddress': 'john.doe@example.com', 
#   'phoneNumber': '+1-555-0100',
#   'isActive': True
# }

# Serialize with snake_case keys (default, no transformation needed)
snake_json = jsons.dump(user)
print(snake_json)
# {
#   'first_name': 'John',
#   'last_name': 'Doe',
#   'email_address': 'john.doe@example.com',
#   'phone_number': '+1-555-0100', 
#   'is_active': True
# }

Key Transformation in Deserialization

import jsons
from jsons import KEY_TRANSFORMER_SNAKECASE, KEY_TRANSFORMER_CAMELCASE
from dataclasses import dataclass

@dataclass
class APIResponse:
    user_id: int
    user_name: str
    created_at: str
    is_verified: bool

# Deserialize from camelCase JSON (common in JavaScript APIs)
camel_data = {
    'userId': 12345,
    'userName': 'alice_smith',
    'createdAt': '2023-12-01T10:30:00Z',
    'isVerified': True
}

# Transform camelCase keys to snake_case during deserialization
response = jsons.load(camel_data, APIResponse, key_transformer=KEY_TRANSFORMER_SNAKECASE)
print(response.user_id)      # 12345
print(response.user_name)    # 'alice_smith'
print(response.created_at)   # '2023-12-01T10:30:00Z'
print(response.is_verified)  # True

Bidirectional API Integration

import jsons
from jsons import KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE
from dataclasses import dataclass
from typing import List

@dataclass
class ProductInfo:
    product_id: int
    product_name: str
    unit_price: float
    in_stock: bool
    category_tags: List[str]

# Python uses snake_case internally
product = ProductInfo(
    product_id=101,
    product_name="Wireless Headphones",
    unit_price=99.99,
    in_stock=True,
    category_tags=["electronics", "audio", "wireless"]
)

# Send to JavaScript API (requires camelCase)
api_payload = jsons.dump(product, key_transformer=KEY_TRANSFORMER_CAMELCASE)
print("Sending to API:")
print(api_payload)
# {
#   'productId': 101,
#   'productName': 'Wireless Headphones', 
#   'unitPrice': 99.99,
#   'inStock': True,
#   'categoryTags': ['electronics', 'audio', 'wireless']
# }

# Receive from JavaScript API (camelCase format)
api_response = {
    'productId': 102, 
    'productName': 'Bluetooth Speaker',
    'unitPrice': 79.99,
    'inStock': False,
    'categoryTags': ['electronics', 'audio', 'bluetooth']
}

# Convert back to Python object with snake_case
received_product = jsons.load(api_response, ProductInfo, key_transformer=KEY_TRANSFORMER_SNAKECASE)
print("Received from API:")
print(f"Product: {received_product.product_name}")
print(f"Price: ${received_product.unit_price}")
print(f"Available: {received_product.in_stock}")

Custom JsonSerializable with Key Transformation

import jsons
from jsons import JsonSerializable, KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE

# Create specialized classes for different API formats  
JavaScriptAPI = JsonSerializable.with_dump(
    key_transformer=KEY_TRANSFORMER_CAMELCASE
).with_load(
    key_transformer=KEY_TRANSFORMER_SNAKECASE
)

class WebUser(JavaScriptAPI):
    def __init__(self, user_id: int, full_name: str, email_address: str):
        self.user_id = user_id
        self.full_name = full_name
        self.email_address = email_address

user = WebUser(123, "Jane Doe", "jane@example.com")

# Automatically uses camelCase for JSON output
user_json = user.json
print(user_json)
# {'userId': 123, 'fullName': 'Jane Doe', 'emailAddress': 'jane@example.com'}

# Automatically converts camelCase input to snake_case attributes
camel_input = {'userId': 456, 'fullName': 'Bob Smith', 'emailAddress': 'bob@example.com'}
new_user = WebUser.from_json(camel_input)
print(new_user.user_id)       # 456
print(new_user.full_name)     # 'Bob Smith'
print(new_user.email_address) # 'bob@example.com'

Complex Nested Key Transformation

import jsons
from jsons import KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE
from dataclasses import dataclass
from typing import Dict, List

@dataclass
class ContactInfo:
    phone_number: str
    email_address: str
    home_address: str

@dataclass  
class EmployeeRecord:
    employee_id: int
    first_name: str
    last_name: str
    contact_info: ContactInfo
    skill_ratings: Dict[str, int]
    project_history: List[str]

# Create complex nested object
employee = EmployeeRecord(
    employee_id=1001,
    first_name="Sarah",
    last_name="Johnson", 
    contact_info=ContactInfo(
        phone_number="555-0123",
        email_address="sarah.j@company.com",
        home_address="123 Oak Street"
    ),
    skill_ratings={"python_programming": 9, "project_management": 8, "data_analysis": 7},
    project_history=["web_redesign", "mobile_app", "data_migration"]
)

# Transform all nested keys to camelCase
camel_json = jsons.dump(employee, key_transformer=KEY_TRANSFORMER_CAMELCASE)
print(camel_json)
# {
#   'employeeId': 1001,
#   'firstName': 'Sarah',
#   'lastName': 'Johnson',
#   'contactInfo': {
#     'phoneNumber': '555-0123',
#     'emailAddress': 'sarah.j@company.com', 
#     'homeAddress': '123 Oak Street'
#   },
#   'skillRatings': {'pythonProgramming': 9, 'projectManagement': 8, 'dataAnalysis': 7},
#   'projectHistory': ['web_redesign', 'mobile_app', 'data_migration']
# }

# Deserialize camelCase back to snake_case structure
restored_employee = jsons.load(camel_json, EmployeeRecord, key_transformer=KEY_TRANSFORMER_SNAKECASE)
print(restored_employee.employee_id)  # 1001
print(restored_employee.contact_info.phone_number)  # '555-0123'
print(restored_employee.skill_ratings['python_programming'])  # 9

Working with Different API Styles

import jsons
from jsons import KEY_TRANSFORMER_PASCALCASE, KEY_TRANSFORMER_LISPCASE, KEY_TRANSFORMER_SNAKECASE
from dataclasses import dataclass

@dataclass
class ConfigData:
    server_host: str
    server_port: int
    database_url: str
    cache_timeout: int
    debug_mode: bool

config = ConfigData(
    server_host="localhost",
    server_port=8080,
    database_url="postgresql://localhost/mydb", 
    cache_timeout=300,
    debug_mode=True
)

# Generate different formats for different systems
formats = {
    "JavaScript API": jsons.dump(config, key_transformer=jsons.camelcase),
    "C# API": jsons.dump(config, key_transformer=KEY_TRANSFORMER_PASCALCASE), 
    "Lisp/Clojure": jsons.dump(config, key_transformer=KEY_TRANSFORMER_LISPCASE),
    "Python/Ruby": jsons.dump(config, key_transformer=KEY_TRANSFORMER_SNAKECASE)
}

for system, format_data in formats.items():
    print(f"{system}:")
    print(format_data)
    print()

# Output:
# JavaScript API:
# {'serverHost': 'localhost', 'serverPort': 8080, 'databaseUrl': '...', 'cacheTimeout': 300, 'debugMode': True}
#
# C# API:  
# {'ServerHost': 'localhost', 'ServerPort': 8080, 'DatabaseUrl': '...', 'CacheTimeout': 300, 'DebugMode': True}
#
# Lisp/Clojure:
# {'server-host': 'localhost', 'server-port': 8080, 'database-url': '...', 'cache-timeout': 300, 'debug-mode': True}
#
# Python/Ruby:
# {'server_host': 'localhost', 'server_port': 8080, 'database_url': '...', 'cache_timeout': 300, 'debug_mode': True}

Install with Tessl CLI

npx tessl i tessl/pypi-jsons

docs

class-integration.md

configuration.md

core-serialization.md

customization.md

index.md

key-transformation.md

type-system.md

tile.json