Skip to content

Commit

Permalink
Merge pull request #38 from frol/fix-dump_only-fields
Browse files Browse the repository at this point in the history
Dump-only fields must be skipped if 'dump=False' is passed
  • Loading branch information
sloria committed Nov 23, 2015
2 parents 9e4a8c9 + e16fdb5 commit ff72e97
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ Contributors (chronological)
============================

- Josh Johnston `@Trii <https://github.com/Trii>`_
- Vlad Frolov `@frol <https://github.com/frol>`_
4 changes: 4 additions & 0 deletions apispec/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ class APISpecError(Exception):
class PluginError(APISpecError):
"""Raised when a plugin cannot be found or is invalid."""
pass

class SwaggerError(APISpecError):
"""Raised when a swagger validation fails"""
pass
4 changes: 2 additions & 2 deletions apispec/ext/marshmallow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ def schema_path_helper(spec, view, **kwargs):
response['schema'] = resolve_schema_dict(spec, response['schema'])
return Path(operations=operations)

def resolve_schema_dict(spec, schema):
def resolve_schema_dict(spec, schema, dump=True):
if isinstance(schema, dict):
return schema
plug = spec.plugins[NAME] if spec else {}
schema_cls = resolve_schema_cls(schema)
if schema_cls in plug.get('refs', {}):
return {'$ref': '#/definitions/{0}'.format(plug['refs'][schema_cls])}
return swagger.schema2jsonschema(schema_cls, spec=spec)
return swagger.schema2jsonschema(schema_cls, spec=spec, dump=dump)

def resolve_schema_cls(schema):
if isinstance(schema, type) and issubclass(schema, marshmallow.Schema):
Expand Down
18 changes: 12 additions & 6 deletions apispec/ext/marshmallow/swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,11 @@ def fields2parameters(fields, schema_cls=None, spec=None, use_refs=True, dump=Tr
if schema_cls is not None:
# Prevent circular import
from apispec.ext.marshmallow import resolve_schema_dict
prop = resolve_schema_dict(spec, schema_cls)
prop = resolve_schema_dict(spec, schema_cls, dump=dump)
else:
prop = fields2jsonschema(fields, schema_cls=schema_cls, spec=spec, use_refs=use_refs)
prop = fields2jsonschema(
fields, schema_cls=schema_cls, spec=spec, use_refs=use_refs, dump=dump
)
return [{
'in': default_in,
'required': required,
Expand All @@ -152,7 +154,11 @@ def fields2parameters(fields, schema_cls=None, spec=None, use_refs=True, dump=Tr
field2parameter(field_obj, name=field_name, spec=spec,
use_refs=use_refs, dump=dump, default_in=default_in)
for field_name, field_obj in iteritems(fields)
if field_name not in getattr(Meta, 'exclude', [])
if (
(field_name not in getattr(Meta, 'exclude', []))
and
not (field_obj.dump_only and not dump)
)
]


Expand Down Expand Up @@ -217,9 +223,9 @@ def property2parameter(prop, name='body', required=False, multiple=False, locati
return ret


def schema2jsonschema(schema_cls, spec=None, use_refs=True):
def schema2jsonschema(schema_cls, spec=None, use_refs=True, dump=True):
fields = schema_cls._declared_fields
return fields2jsonschema(fields, schema_cls, spec=spec, use_refs=use_refs)
return fields2jsonschema(fields, schema_cls, spec=spec, use_refs=use_refs, dump=dump)


def fields2jsonschema(fields, schema_cls=None, spec=None, use_refs=True, dump=True):
Expand Down Expand Up @@ -268,7 +274,7 @@ class Meta:
ret = {'properties': {}}
exclude = set(getattr(Meta, 'exclude', []))
for field_name, field_obj in iteritems(fields):
if field_name in exclude:
if field_name in exclude or (field_obj.dump_only and not dump):
continue
prop = field2property(field_obj, spec=spec, use_refs=use_refs, dump=dump)
ret['properties'][field_name] = prop
Expand Down
2 changes: 1 addition & 1 deletion tests/schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from marshmallow import Schema, fields

class PetSchema(Schema):
id = fields.Int()
id = fields.Int(dump_only=True)
name = fields.Str()
24 changes: 24 additions & 0 deletions tests/test_swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ def test_fields_with_default_load(self):
res = swagger.fields2parameters(field_dict, default_in='query', dump=False)
assert res[0]['default'] == 'bar'

def test_fields_with_dump_only(self):
field_dict = {'field': fields.Str(dump_only=True)}
res = swagger.fields2parameters(field_dict, default_in='query', dump=False)
assert len(res) == 0

def test_field_with_choices(self):
field = fields.Str(validate=validate.OneOf(['freddie', 'brian', 'john']))
res = swagger.field2property(field)
Expand Down Expand Up @@ -355,6 +360,25 @@ class UserSchema(Schema):
assert param['in'] == 'body'
assert param['schema'] == swagger.schema2jsonschema(UserSchema)

def test_schema_body_with_dump_only(self):
class UserSchema(Schema):
name = fields.Str()
email = fields.Email(dump_only=True)

res_dump = swagger.schema2parameters(UserSchema, default_in='body', dump=True)
assert len(res_dump) == 1
param = res_dump[0]
assert param['in'] == 'body'
assert param['schema'] == swagger.schema2jsonschema(UserSchema, dump=True)
assert set(param['schema']['properties'].keys()) == {'name', 'email'}

res_nodump = swagger.schema2parameters(UserSchema, default_in='body', dump=False)
assert len(res_nodump) == 1
param = res_nodump[0]
assert param['in'] == 'body'
assert param['schema'] == swagger.schema2jsonschema(UserSchema, dump=False)
assert set(param['schema']['properties'].keys()) == {'name'}

def test_schema_query(self):
class UserSchema(Schema):
name = fields.Str()
Expand Down

0 comments on commit ff72e97

Please sign in to comment.