You don't convert your keys, because you don't need to. Data is not code, the keys in JSON are not variables. They are not subject to PEP8 and you don't convert them.
If you have a convention for your JSON object keys, stick to it everywhere, in your front end and back end. Then use the Marshmallow 3.x data_key
argument for a field to set the key name in the JSON document when loading and dumping.
E.g.
class UserSchema(Schema):
first_name = fields.String(data_key="firstName")
last_name = fields.Email(data_key='lastName')
If you want to automate this for all your fields, you could provide your own Schema.on_bind_field()
implementation to generate a data_key
value from the field name:
import re
from functools import partial
from marshmallow import Schema
_snake_case = re.compile(r"(?<=\w)_(\w)")
_to_camel_case = partial(_snake_case.sub, lambda m: m[1].upper())
class CamelCasedSchema(Schema):
"""Gives fields a camelCased data key"""
def on_bind_field(self, field_name, field_obj, _cc=_to_camel_case):
field_obj.data_key = _cc(field_name.lower())
Demo:
>>> from marshmallow import fields
>>> class UserSchema(CamelCasedSchema):
... first_name = fields.String()
... last_name = fields.String()
...
>>> schema = UserSchema()
>>> schema.load({"firstName": "Eric", "lastName": "Idle"})
{'first_name': 'Eric', 'last_name': 'Idle'}
>>> schema.dump({"first_name": "John", "last_name": "Cleese"})
{'firstName': 'John', 'lastName': 'Cleese'}
The examples section of the Marshmallow documentation has a similar recipe.
If you are using Marshmallow 2.x, then there are two arguments to set: load_from
and dump_to
.