or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

class-integration.mdconfiguration.mdcore-serialization.mdcustomization.mdindex.mdkey-transformation.mdtype-system.md

key-transformation.mddocs/

0

# Key Transformation

1

2

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.

3

4

## Capabilities

5

6

### Case Transformation Functions

7

8

```python { .api }

9

def camelcase(str_):

10

"""

11

Transform string to camelCase format.

12

13

Parameters:

14

- str_: String to be transformed

15

16

Returns:

17

str: String in camelCase format (first letter lowercase, subsequent words capitalized)

18

19

Examples:

20

- 'hello_world' -> 'helloWorld'

21

- 'user-name' -> 'userName'

22

- 'API_KEY' -> 'apiKey'

23

"""

24

25

def snakecase(str_):

26

"""

27

Transform string to snake_case format.

28

29

Parameters:

30

- str_: String to be transformed

31

32

Returns:

33

str: String in snake_case format (all lowercase with underscores)

34

35

Examples:

36

- 'helloWorld' -> 'hello_world'

37

- 'UserName' -> 'user_name'

38

- 'API-Key' -> 'api_key'

39

"""

40

41

def pascalcase(str_):

42

"""

43

Transform string to PascalCase format.

44

45

Parameters:

46

- str_: String to be transformed

47

48

Returns:

49

str: String in PascalCase format (first letter uppercase, subsequent words capitalized)

50

51

Examples:

52

- 'hello_world' -> 'HelloWorld'

53

- 'user-name' -> 'UserName'

54

- 'api_key' -> 'ApiKey'

55

"""

56

57

def lispcase(str_):

58

"""

59

Transform string to lisp-case format.

60

61

Parameters:

62

- str_: String to be transformed

63

64

Returns:

65

str: String in lisp-case format (all lowercase with hyphens)

66

67

Examples:

68

- 'helloWorld' -> 'hello-world'

69

- 'UserName' -> 'user-name'

70

- 'api_key' -> 'api-key'

71

"""

72

```

73

74

### Key Transformer Constants

75

76

```python { .api }

77

# Pre-defined constants for use with dump/load functions

78

KEY_TRANSFORMER_SNAKECASE = snakecase

79

KEY_TRANSFORMER_CAMELCASE = camelcase

80

KEY_TRANSFORMER_PASCALCASE = pascalcase

81

KEY_TRANSFORMER_LISPCASE = lispcase

82

```

83

84

## Usage Examples

85

86

### Basic Key Transformation

87

88

```python

89

import jsons

90

from jsons import camelcase, snakecase, pascalcase, lispcase

91

92

# Transform individual strings

93

original = "user_profile_data"

94

95

print(camelcase(original)) # 'userProfileData'

96

print(snakecase(original)) # 'user_profile_data' (no change)

97

print(pascalcase(original)) # 'UserProfileData'

98

print(lispcase(original)) # 'user-profile-data'

99

100

# Transform from camelCase

101

camel_string = "firstName"

102

print(snakecase(camel_string)) # 'first_name'

103

print(pascalcase(camel_string)) # 'FirstName'

104

print(lispcase(camel_string)) # 'first-name'

105

106

# Transform with hyphens and mixed formats

107

mixed_string = "API-Response-Data"

108

print(camelcase(mixed_string)) # 'apiResponseData'

109

print(snakecase(mixed_string)) # 'api_response_data'

110

print(pascalcase(mixed_string)) # 'ApiResponseData'

111

```

112

113

### Key Transformation in Serialization

114

115

```python

116

import jsons

117

from jsons import KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE

118

from dataclasses import dataclass

119

120

@dataclass

121

class UserProfile:

122

first_name: str

123

last_name: str

124

email_address: str

125

phone_number: str

126

is_active: bool

127

128

user = UserProfile(

129

first_name="John",

130

last_name="Doe",

131

email_address="john.doe@example.com",

132

phone_number="+1-555-0100",

133

is_active=True

134

)

135

136

# Serialize with camelCase keys

137

camel_json = jsons.dump(user, key_transformer=KEY_TRANSFORMER_CAMELCASE)

138

print(camel_json)

139

# {

140

# 'firstName': 'John',

141

# 'lastName': 'Doe',

142

# 'emailAddress': 'john.doe@example.com',

143

# 'phoneNumber': '+1-555-0100',

144

# 'isActive': True

145

# }

146

147

# Serialize with snake_case keys (default, no transformation needed)

148

snake_json = jsons.dump(user)

149

print(snake_json)

150

# {

151

# 'first_name': 'John',

152

# 'last_name': 'Doe',

153

# 'email_address': 'john.doe@example.com',

154

# 'phone_number': '+1-555-0100',

155

# 'is_active': True

156

# }

157

```

158

159

### Key Transformation in Deserialization

160

161

```python

162

import jsons

163

from jsons import KEY_TRANSFORMER_SNAKECASE, KEY_TRANSFORMER_CAMELCASE

164

from dataclasses import dataclass

165

166

@dataclass

167

class APIResponse:

168

user_id: int

169

user_name: str

170

created_at: str

171

is_verified: bool

172

173

# Deserialize from camelCase JSON (common in JavaScript APIs)

174

camel_data = {

175

'userId': 12345,

176

'userName': 'alice_smith',

177

'createdAt': '2023-12-01T10:30:00Z',

178

'isVerified': True

179

}

180

181

# Transform camelCase keys to snake_case during deserialization

182

response = jsons.load(camel_data, APIResponse, key_transformer=KEY_TRANSFORMER_SNAKECASE)

183

print(response.user_id) # 12345

184

print(response.user_name) # 'alice_smith'

185

print(response.created_at) # '2023-12-01T10:30:00Z'

186

print(response.is_verified) # True

187

```

188

189

### Bidirectional API Integration

190

191

```python

192

import jsons

193

from jsons import KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE

194

from dataclasses import dataclass

195

from typing import List

196

197

@dataclass

198

class ProductInfo:

199

product_id: int

200

product_name: str

201

unit_price: float

202

in_stock: bool

203

category_tags: List[str]

204

205

# Python uses snake_case internally

206

product = ProductInfo(

207

product_id=101,

208

product_name="Wireless Headphones",

209

unit_price=99.99,

210

in_stock=True,

211

category_tags=["electronics", "audio", "wireless"]

212

)

213

214

# Send to JavaScript API (requires camelCase)

215

api_payload = jsons.dump(product, key_transformer=KEY_TRANSFORMER_CAMELCASE)

216

print("Sending to API:")

217

print(api_payload)

218

# {

219

# 'productId': 101,

220

# 'productName': 'Wireless Headphones',

221

# 'unitPrice': 99.99,

222

# 'inStock': True,

223

# 'categoryTags': ['electronics', 'audio', 'wireless']

224

# }

225

226

# Receive from JavaScript API (camelCase format)

227

api_response = {

228

'productId': 102,

229

'productName': 'Bluetooth Speaker',

230

'unitPrice': 79.99,

231

'inStock': False,

232

'categoryTags': ['electronics', 'audio', 'bluetooth']

233

}

234

235

# Convert back to Python object with snake_case

236

received_product = jsons.load(api_response, ProductInfo, key_transformer=KEY_TRANSFORMER_SNAKECASE)

237

print("Received from API:")

238

print(f"Product: {received_product.product_name}")

239

print(f"Price: ${received_product.unit_price}")

240

print(f"Available: {received_product.in_stock}")

241

```

242

243

### Custom JsonSerializable with Key Transformation

244

245

```python

246

import jsons

247

from jsons import JsonSerializable, KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE

248

249

# Create specialized classes for different API formats

250

JavaScriptAPI = JsonSerializable.with_dump(

251

key_transformer=KEY_TRANSFORMER_CAMELCASE

252

).with_load(

253

key_transformer=KEY_TRANSFORMER_SNAKECASE

254

)

255

256

class WebUser(JavaScriptAPI):

257

def __init__(self, user_id: int, full_name: str, email_address: str):

258

self.user_id = user_id

259

self.full_name = full_name

260

self.email_address = email_address

261

262

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

263

264

# Automatically uses camelCase for JSON output

265

user_json = user.json

266

print(user_json)

267

# {'userId': 123, 'fullName': 'Jane Doe', 'emailAddress': 'jane@example.com'}

268

269

# Automatically converts camelCase input to snake_case attributes

270

camel_input = {'userId': 456, 'fullName': 'Bob Smith', 'emailAddress': 'bob@example.com'}

271

new_user = WebUser.from_json(camel_input)

272

print(new_user.user_id) # 456

273

print(new_user.full_name) # 'Bob Smith'

274

print(new_user.email_address) # 'bob@example.com'

275

```

276

277

### Complex Nested Key Transformation

278

279

```python

280

import jsons

281

from jsons import KEY_TRANSFORMER_CAMELCASE, KEY_TRANSFORMER_SNAKECASE

282

from dataclasses import dataclass

283

from typing import Dict, List

284

285

@dataclass

286

class ContactInfo:

287

phone_number: str

288

email_address: str

289

home_address: str

290

291

@dataclass

292

class EmployeeRecord:

293

employee_id: int

294

first_name: str

295

last_name: str

296

contact_info: ContactInfo

297

skill_ratings: Dict[str, int]

298

project_history: List[str]

299

300

# Create complex nested object

301

employee = EmployeeRecord(

302

employee_id=1001,

303

first_name="Sarah",

304

last_name="Johnson",

305

contact_info=ContactInfo(

306

phone_number="555-0123",

307

email_address="sarah.j@company.com",

308

home_address="123 Oak Street"

309

),

310

skill_ratings={"python_programming": 9, "project_management": 8, "data_analysis": 7},

311

project_history=["web_redesign", "mobile_app", "data_migration"]

312

)

313

314

# Transform all nested keys to camelCase

315

camel_json = jsons.dump(employee, key_transformer=KEY_TRANSFORMER_CAMELCASE)

316

print(camel_json)

317

# {

318

# 'employeeId': 1001,

319

# 'firstName': 'Sarah',

320

# 'lastName': 'Johnson',

321

# 'contactInfo': {

322

# 'phoneNumber': '555-0123',

323

# 'emailAddress': 'sarah.j@company.com',

324

# 'homeAddress': '123 Oak Street'

325

# },

326

# 'skillRatings': {'pythonProgramming': 9, 'projectManagement': 8, 'dataAnalysis': 7},

327

# 'projectHistory': ['web_redesign', 'mobile_app', 'data_migration']

328

# }

329

330

# Deserialize camelCase back to snake_case structure

331

restored_employee = jsons.load(camel_json, EmployeeRecord, key_transformer=KEY_TRANSFORMER_SNAKECASE)

332

print(restored_employee.employee_id) # 1001

333

print(restored_employee.contact_info.phone_number) # '555-0123'

334

print(restored_employee.skill_ratings['python_programming']) # 9

335

```

336

337

### Working with Different API Styles

338

339

```python

340

import jsons

341

from jsons import KEY_TRANSFORMER_PASCALCASE, KEY_TRANSFORMER_LISPCASE, KEY_TRANSFORMER_SNAKECASE

342

from dataclasses import dataclass

343

344

@dataclass

345

class ConfigData:

346

server_host: str

347

server_port: int

348

database_url: str

349

cache_timeout: int

350

debug_mode: bool

351

352

config = ConfigData(

353

server_host="localhost",

354

server_port=8080,

355

database_url="postgresql://localhost/mydb",

356

cache_timeout=300,

357

debug_mode=True

358

)

359

360

# Generate different formats for different systems

361

formats = {

362

"JavaScript API": jsons.dump(config, key_transformer=jsons.camelcase),

363

"C# API": jsons.dump(config, key_transformer=KEY_TRANSFORMER_PASCALCASE),

364

"Lisp/Clojure": jsons.dump(config, key_transformer=KEY_TRANSFORMER_LISPCASE),

365

"Python/Ruby": jsons.dump(config, key_transformer=KEY_TRANSFORMER_SNAKECASE)

366

}

367

368

for system, format_data in formats.items():

369

print(f"{system}:")

370

print(format_data)

371

print()

372

373

# Output:

374

# JavaScript API:

375

# {'serverHost': 'localhost', 'serverPort': 8080, 'databaseUrl': '...', 'cacheTimeout': 300, 'debugMode': True}

376

#

377

# C# API:

378

# {'ServerHost': 'localhost', 'ServerPort': 8080, 'DatabaseUrl': '...', 'CacheTimeout': 300, 'DebugMode': True}

379

#

380

# Lisp/Clojure:

381

# {'server-host': 'localhost', 'server-port': 8080, 'database-url': '...', 'cache-timeout': 300, 'debug-mode': True}

382

#

383

# Python/Ruby:

384

# {'server_host': 'localhost', 'server_port': 8080, 'database_url': '...', 'cache_timeout': 300, 'debug_mode': True}

385

```