Skip to content

Commit

Permalink
Merge pull request #173 from Teyras/master
Browse files Browse the repository at this point in the history
Merge specs_dict recursively instead of just updating the top level
  • Loading branch information
rochacbruno committed Dec 6, 2017
2 parents 8adba14 + a4f9525 commit 73c4fc3
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 5 deletions.
48 changes: 48 additions & 0 deletions examples/swag_from_merging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from flask import Flask
from flask import jsonify
from flasgger import Swagger
from flasgger import swag_from

app = Flask(__name__)
swag = Swagger(app)


@app.route("/example")
@swag_from({
"responses": {
400: {
"description": "Invalid action"
},
401: {
"description": "Login required"
}
},
"tags": ["Tag 1", "Tag 2"]
})
def view():
"""
A test view
---
responses:
200:
description: OK
tags: [Tag 3, Tag 4]
"""
return jsonify(hello="world")


def test_swag(client, specs_data):
example_spec = specs_data["/apispec_1.json"]["paths"]["/example"]["get"]
assert "400" in example_spec["responses"]
assert "401" in example_spec["responses"]
assert "200" in example_spec["responses"]

assert "Tag 1" in example_spec["tags"]
assert "Tag 2" in example_spec["tags"]
assert "Tag 3" in example_spec["tags"]
assert "Tag 4" in example_spec["tags"]


if __name__ == "__main__":
app.run(debug=True)
45 changes: 45 additions & 0 deletions examples/swag_from_overriding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from flask import Flask
from flask import jsonify
from flasgger import Swagger
from flasgger import swag_from

app = Flask(__name__)
swag = Swagger(app)


@app.route("/example")
@swag_from({
"responses": {
400: {
"description": "Invalid action"
},
401: {
"description": "Login required"
}
}
})
def view():
"""
A test view
---
responses:
200:
description: OK
400:
description: Modified description
"""
return jsonify(hello="world")


def test_swag(client, specs_data):
example_spec = specs_data["/apispec_1.json"]["paths"]["/example"]["get"]
assert "400" in example_spec["responses"]
assert "401" in example_spec["responses"]
assert "200" in example_spec["responses"]

assert example_spec["responses"]["400"]["description"] == "Modified description"


if __name__ == "__main__":
app.run(debug=True)
27 changes: 22 additions & 5 deletions flasgger/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@
from .marshmallow_apispec import convert_schemas


def merge_specs(target, source):
"""
Update target dictionary with values from the source, recursively.
List items will be merged.
"""

for key, value in source.items():
if isinstance(value, dict):
node = target.setdefault(key, {})
merge_specs(node, value)
elif isinstance(value, list):
node = target.setdefault(key, [])
node.extend(value)
else:
target[key] = value


def get_schema_specs(schema_id, swagger):
ignore_verbs = set(
swagger.config.get('ignore_verbs', ("HEAD", "OPTIONS")))
Expand Down Expand Up @@ -87,6 +104,10 @@ def get_specs(rules, ignore_verbs, optional_fields, sanitizer):
swag = {}
swagged = False

if getattr(method, 'specs_dict', None):
merge_specs(swag, deepcopy(method.specs_dict))
swagged = True

view_class = getattr(endpoint, 'view_class', None)
if view_class and issubclass(view_class, SwaggerView):
apispec_swag = {}
Expand All @@ -106,15 +127,11 @@ def get_specs(rules, ignore_verbs, optional_fields, sanitizer):

swagged = True

if getattr(method, 'specs_dict', None):
swag.update(deepcopy(method.specs_dict))
swagged = True

doc_summary, doc_description, doc_swag = parse_docstring(
method, sanitizer, endpoint=rule.endpoint, verb=verb)

if doc_swag:
swag.update(doc_swag or {})
merge_specs(swag, doc_swag)
swagged = True

if swagged:
Expand Down

0 comments on commit 73c4fc3

Please sign in to comment.