Skip to content

Commit 804739a

Browse files
committed
Improve handling of potentially invalid openapi versions
1 parent d9680d2 commit 804739a

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/apifairy/core.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
except ImportError: # pragma: no cover
2020
HTTPBasicAuth = None
2121
HTTPTokenAuth = None
22+
from packaging.version import Version
2223
from werkzeug.http import HTTP_STATUS_CODES
2324

2425
from apifairy.decorators import _webhooks
@@ -46,7 +47,8 @@ def init_app(self, app):
4647
self.version = app.config.get('APIFAIRY_VERSION', 'No version')
4748
self.apispec_path = app.config.get('APIFAIRY_APISPEC_PATH',
4849
'/apispec.json')
49-
self.apispec_version = app.config.get('APIFAIRY_APISPEC_VERSION', None)
50+
self.apispec_version = app.config.get('APIFAIRY_APISPEC_VERSION',
51+
'3.0.3')
5052
self.apispec_decorators = app.config.get(
5153
'APIFAIRY_APISPEC_DECORATORS', [])
5254
self.ui = app.config.get('APIFAIRY_UI', 'redoc')
@@ -148,11 +150,13 @@ def resolver(schema):
148150
tags[name] = tag
149151
tag_list = [tags[name] for name in tag_names]
150152
ma_plugin = MarshmallowPlugin(schema_name_resolver=resolver)
151-
oas_version = '3.1.0' if _webhooks else self.apispec_version or '3.0.3'
153+
if Version(self.apispec_version) < Version('3.1.0') and _webhooks:
154+
raise RuntimeError("Must use at least openapi version '3.1.0' "
155+
'when using the @webhook decorator')
152156
spec = APISpec(
153157
title=self.title,
154158
version=self.version,
155-
openapi_version=oas_version,
159+
openapi_version=self.apispec_version,
156160
plugins=[ma_plugin],
157161
info=info,
158162
servers=servers,

tests/test_apifairy.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def test_custom_apispec_version(self):
151151
assert rv.json['openapi'] == '3.1.0'
152152

153153
def test_custom_apispec_no_version(self):
154-
app, _ = self.create_app(config={'APIFAIRY_APISPEC_VERSION': None})
154+
app, _ = self.create_app()
155155

156156
client = app.test_client()
157157
rv = client.get('/apispec.json')
@@ -160,6 +160,22 @@ def test_custom_apispec_no_version(self):
160160
'openapi', 'info', 'servers', 'paths', 'tags'}
161161
assert rv.json['openapi'] == '3.0.3'
162162

163+
def test_custom_apispec_invalid_version(self):
164+
app, _ = self.create_app(
165+
config={'APIFAIRY_APISPEC_VERSION': '4.0.0'})
166+
167+
client = app.test_client()
168+
rv = client.get('/apispec.json')
169+
assert rv.status_code == 500
170+
171+
def test_custom_apispec_non_semver_version(self):
172+
app, _ = self.create_app(
173+
config={'APIFAIRY_APISPEC_VERSION': 'invalid'})
174+
175+
client = app.test_client()
176+
rv = client.get('/apispec.json')
177+
assert rv.status_code == 500
178+
163179
def test_ui(self):
164180
app, _ = self.create_app(config={'APIFAIRY_UI': 'swagger_ui'})
165181

@@ -1014,7 +1030,8 @@ async def foo(query, body):
10141030
assert rv.json == {'id': 2, 'name': 'foo'}
10151031

10161032
def test_webhook(self):
1017-
app, apifairy = self.create_app()
1033+
app, apifairy = self.create_app(
1034+
config={'APIFAIRY_APISPEC_VERSION': '3.1.0'})
10181035
bp = Blueprint('bp', __name__)
10191036

10201037
@webhook
@@ -1060,6 +1077,19 @@ def blueprint_webhook():
10601077
assert 'blueprint_webhook' in rv.json['webhooks']
10611078
assert 'get' in rv.json['webhooks']['blueprint_webhook']
10621079

1080+
def test_webhook_invalid_apispec_version(self):
1081+
app, apifairy = self.create_app(
1082+
config={'APIFAIRY_APISPEC_VERSION': '3.0.3'})
1083+
1084+
@webhook
1085+
@body(Schema)
1086+
def unsupported_webhook():
1087+
pass
1088+
1089+
client = app.test_client()
1090+
rv = client.get('/apispec.json')
1091+
assert rv.status_code == 500
1092+
10631093
def test_webhook_duplicate(self):
10641094
app, apifairy = self.create_app()
10651095

0 commit comments

Comments
 (0)