Skip to content

Commit 435cc03

Browse files
committed
Make compatible with apispec>=0.39.0
Close #105
1 parent d4269cc commit 435cc03

File tree

6 files changed

+60
-28
lines changed

6 files changed

+60
-28
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: python
22
sudo: false
33
env:
4-
- APISPEC_VERSION="==0.17.0"
4+
- APISPEC_VERSION="==0.39.0"
55
- APISPEC_VERSION=""
66
- MARSHMALLOW_VERSION="==2.13.0"
77
- MARSHMALLOW_VERSION=""

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Changelog
22
---------
33

4+
0.7.0 (unreleased)
5+
++++++++++++++++++
6+
7+
Features:
8+
9+
* Supports apispec>=0.39.0. Older apispec versions are no longer supported.
10+
411
0.6.1 (2018-06-25)
512
++++++++++++++++++
613

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,14 @@ Quickstart
8787
.. code-block:: python
8888
8989
from apispec import APISpec
90+
from apispec.ext.marshmallow import MarshmallowPlugin
9091
from flask_apispec.extension import FlaskApiSpec
9192
9293
app.config.update({
9394
'APISPEC_SPEC': APISpec(
9495
title='pets',
9596
version='v1',
96-
plugins=['apispec.ext.marshmallow'],
97+
plugins=[MarshmallowPlugin()],
9798
),
9899
'APISPEC_SWAGGER_URL': '/swagger/',
99100
})

flask_apispec/apidoc.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import apispec
99
from apispec.core import VALID_METHODS
10-
from apispec.ext.marshmallow import swagger
10+
from apispec.ext.marshmallow import MarshmallowPlugin
1111

1212
from marshmallow import Schema
1313
from marshmallow.utils import is_instance_or_subclass
@@ -17,8 +17,19 @@
1717

1818
class Converter(object):
1919

20-
def __init__(self, app):
20+
def __init__(self, app, spec):
2121
self.app = app
22+
self.spec = spec
23+
try:
24+
self.marshmallow_plugin = next(
25+
plugin for plugin in self.spec.plugins
26+
if isinstance(plugin, MarshmallowPlugin)
27+
)
28+
except StopIteration:
29+
raise RuntimeError(
30+
"Must have a MarshmallowPlugin instance in the spec's list "
31+
'of plugins.'
32+
)
2233

2334
def convert(self, target, endpoint=None, blueprint=None, **kwargs):
2435
endpoint = endpoint or target.__name__.lower()
@@ -57,19 +68,20 @@ def get_parent(self, view):
5768
return None
5869

5970
def get_parameters(self, rule, view, docs, parent=None):
71+
openapi = self.marshmallow_plugin.openapi
6072
annotation = resolve_annotations(view, 'args', parent)
6173
args = merge_recursive(annotation.options)
6274
schema = args.get('args', {})
6375
if is_instance_or_subclass(schema, Schema):
64-
converter = swagger.schema2parameters
76+
converter = openapi.schema2parameters
6577
elif callable(schema):
6678
schema = schema(request=None)
6779
if is_instance_or_subclass(schema, Schema):
68-
converter = swagger.schema2parameters
80+
converter = openapi.schema2parameters
6981
else:
70-
converter = swagger.fields2parameters
82+
converter = openapi.fields2parameters
7183
else:
72-
converter = swagger.fields2parameters
84+
converter = openapi.fields2parameters
7385
options = copy.copy(args.get('kwargs', {}))
7486
locations = options.pop('locations', None)
7587
if locations:

flask_apispec/extension.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import functools
44
import types
55
from apispec import APISpec
6+
from apispec.ext.marshmallow import MarshmallowPlugin
67

78
from flask_apispec import ResourceMeta
89
from flask_apispec.apidoc import ViewConverter, ResourceConverter
@@ -20,7 +21,7 @@ class FlaskApiSpec(object):
2021
'APISPEC_SPEC': APISpec(
2122
title='pets',
2223
version='v1',
23-
plugins=['apispec.ext.marshmallow'],
24+
plugins=[MarshmallowPlugin()],
2425
),
2526
'APISPEC_SWAGGER_URL': '/swagger/',
2627
})
@@ -48,13 +49,12 @@ def __init__(self, app=None):
4849

4950
def init_app(self, app):
5051
self.app = app
51-
self.view_converter = ViewConverter(self.app)
52-
self.resource_converter = ResourceConverter(self.app)
5352
self.spec = self.app.config.get('APISPEC_SPEC') or \
5453
make_apispec(self.app.config.get('APISPEC_TITLE', 'flask-apispec'),
5554
self.app.config.get('APISPEC_VERSION', 'v1'))
56-
5755
self.add_swagger_routes()
56+
self.resource_converter = ResourceConverter(self.app, spec=self.spec)
57+
self.view_converter = ViewConverter(app=self.app, spec=self.spec)
5858

5959
for deferred in self._deferred:
6060
deferred()
@@ -150,5 +150,5 @@ def make_apispec(title='flask-apispec', version='v1'):
150150
return APISpec(
151151
title=title,
152152
version=version,
153-
plugins=['apispec.ext.marshmallow'],
153+
plugins=[MarshmallowPlugin()],
154154
)

tests/test_swagger.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import pytest
44
from apispec import APISpec
5-
from apispec.ext.marshmallow import swagger
5+
from apispec.ext.marshmallow import MarshmallowPlugin
66
from marshmallow import fields, Schema
77
from flask import make_response
88

@@ -11,14 +11,22 @@
1111
from flask_apispec import doc, use_kwargs, marshal_with
1212
from flask_apispec.apidoc import ViewConverter, ResourceConverter
1313

14+
@pytest.fixture()
15+
def marshmallow_plugin():
16+
return MarshmallowPlugin()
17+
1418
@pytest.fixture
15-
def spec():
19+
def spec(marshmallow_plugin):
1620
return APISpec(
1721
title='title',
1822
version='v1',
19-
plugins=['apispec.ext.marshmallow'],
23+
plugins=[marshmallow_plugin],
2024
)
2125

26+
@pytest.fixture()
27+
def openapi(marshmallow_plugin):
28+
return marshmallow_plugin.openapi
29+
2230
class TestFunctionView:
2331

2432
@pytest.fixture
@@ -33,7 +41,7 @@ def get_band(band_id):
3341

3442
@pytest.fixture
3543
def path(self, app, spec, function_view):
36-
converter = ViewConverter(app)
44+
converter = ViewConverter(app=app, spec=spec)
3745
paths = converter.convert(function_view)
3846
for path in paths:
3947
spec.add_path(**path)
@@ -53,10 +61,11 @@ def test_params(self, app, path):
5361
)
5462
assert params == expected
5563

56-
def test_responses(self, schemas, path):
64+
def test_responses(self, schemas, path, openapi):
5765
response = path['get']['responses']['default']
5866
assert response['description'] == 'a band'
59-
assert response['schema'] == swagger.schema2jsonschema(schemas.BandSchema)
67+
expected = openapi.schema2jsonschema(schemas.BandSchema)
68+
assert response['schema'] == expected
6069

6170
def test_tags(self, path):
6271
assert path['get']['tags'] == ['band']
@@ -76,17 +85,18 @@ def get_band(**kwargs):
7685

7786
@pytest.fixture
7887
def path(self, app, spec, function_view):
79-
converter = ViewConverter(app)
88+
converter = ViewConverter(app=app, spec=spec)
8089
paths = converter.convert(function_view)
8190
for path in paths:
8291
spec.add_path(**path)
8392
return spec._paths['/bands/{band_id}/']
8493

85-
def test_params(self, app, path):
94+
def test_params(self, app, path, openapi):
8695
params = path['get']['parameters']
8796
rule = app.url_map._rules_by_endpoint['get_band'][0]
8897
expected = (
89-
swagger.fields2parameters({'name': fields.Str()}, default_in='query') +
98+
openapi.fields2parameters(
99+
{'name': fields.Str()}, default_in='query') +
90100
rule_to_params(rule)
91101
)
92102
assert params == expected
@@ -119,7 +129,7 @@ def delete_band(band_id):
119129

120130
@pytest.fixture
121131
def path(self, app, spec, function_view):
122-
converter = ViewConverter(app)
132+
converter = ViewConverter(app=app, spec=spec)
123133
paths = converter.convert(function_view)
124134
for path in paths:
125135
spec.add_path(**path)
@@ -146,25 +156,27 @@ def get(self, **kwargs):
146156

147157
@pytest.fixture
148158
def path(self, app, spec, resource_view):
149-
converter = ResourceConverter(app)
159+
converter = ResourceConverter(app=app, spec=spec)
150160
paths = converter.convert(resource_view, endpoint='band')
151161
for path in paths:
152162
spec.add_path(**path)
153163
return spec._paths['/bands/{band_id}/']
154164

155-
def test_params(self, app, path):
165+
def test_params(self, app, path, openapi):
156166
params = path['get']['parameters']
157167
rule = app.url_map._rules_by_endpoint['band'][0]
158168
expected = (
159-
swagger.fields2parameters({'name': fields.Str()}, default_in='query') +
169+
openapi.fields2parameters(
170+
{'name': fields.Str()}, default_in='query') +
160171
rule_to_params(rule)
161172
)
162173
assert params == expected
163174

164-
def test_responses(self, schemas, path):
175+
def test_responses(self, schemas, path, openapi):
165176
response = path['get']['responses']['default']
166177
assert response['description'] == 'a band'
167-
assert response['schema'] == swagger.schema2jsonschema(schemas.BandSchema)
178+
expected = openapi.schema2jsonschema(schemas.BandSchema)
179+
assert response['schema'] == expected
168180

169181
def test_tags(self, path):
170182
assert path['get']['tags'] == ['band']

0 commit comments

Comments
 (0)