fuhrysteve/marshmallow-jsonschema

Default field values may be callable

kaos opened this issue · 3 comments

kaos commented

When building the json schema from a marshmallow schema, with a default value being a callable, the resulting schema is not clean to pass to json.dumps() for instance.

json_schema["default"] = field.default

Example

import json
import uuid
from marshmallow import Schema, fields
from marshmallow_jsonschema import JSONSchema

class Test(Schema):
    id = fields.UUID(default=uuid.uuid1)

json.dumps(JSONSchema().dump(Test()))
# >> TypeError: Object of type function is not JSON serializable


# JSONSchema().dump(Test()) >> 
{'$schema': 'http://json-schema.org/draft-07/schema#',
 'definitions': {'Test': {'properties': {'id': {'title': 'id',
     'type': 'string',
     'default': <function uuid.uuid1(node=None, clock_seq=None)>}},
   'type': 'object',
   'additionalProperties': False}},
 '$ref': '#/definitions/Test'}

Both missing and default may be callable values for marshmallow fields: https://marshmallow.readthedocs.io/en/stable/marshmallow.fields.html#marshmallow.fields.Field

Hmm, so I have a fix for this - however in your example, uuid.UUID is not serializable either

 34     def test_default_callable():
 35         class DefaultCallableSchema(Schema):
 36             uuid = fields.UUID(default=uuid.uuid4)
 37  
 38         dumped = JSONSchema().dump(DefaultCallableSchema())
 39  
 40         props = dumped["definitions"]["DefaultCallableSchema"]["properties"]
 41         import pdb; pdb.set_trace()
 42  ->     uuid.UUID(props["uuid"]["default"])
(Pdb) pp props
{'uuid': {'default': UUID('253646fa-5ec3-49e7-8d64-9af77c2b982a'),
          'format': 'uuid',
          'title': 'uuid',
          'type': 'string'}}
(Pdb) import json
(Pdb) json.dumps(props)
*** TypeError: Object of type UUID is not JSON serializable
kaos commented

Oops. That's right. I'll usually have to use a custom json encoder to take care of uuid, datetime and the like.. not sure what approach would be suitable here.

kaos commented

That is actually a separate issue from this one, that there may be data in the schema that is not straight off dumpable with json.dumps.