Skip to content

Commit f54e0aa

Browse files
committed
Making sure all endpoints define at least the minimum common responses
A common pitfall when using this package is the following: you define an endpoint that can result in 400 Bad Request, but you forget to list 400 in the `responses` section of your endpoint in openapi.yaml. This package then instead returns 500 Internal Server error, because it keeps the promise that only defined responses will be allowed (unless you set `enable_request_validation` to `False`, that is). With this commit, all endpoints, by default need to have 200, 400 and 500 on the list of `responses` in openapi.yaml, otherwise the app won't start. Additionally, all endpoints that accept a parameter, also need to have 404 on the list of `responses`. You can skip this check by setting `enable_endpoint_validation` to `False`. Refs #22 Refs #49 (comment) Refs #36
1 parent 60e803a commit f54e0aa

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Some notes:
103103
Provided with `pyramid_openapi3` are a few validation features:
104104
* incoming request validation (i.e. what a client sends to your app)
105105
* outgoing response validation (i.e. what your app sends to a client)
106-
* endpoint validation (i.e. your app registers routes for all defined API endpoints)
106+
* endpoint validation (i.e. all endpoints define minimal responses and have routes registered)
107107

108108
These features are enabled as a default, but you can disable them if you need to:
109109

pyramid_openapi3/__init__.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def includeme(config: Configurator) -> None:
4242
config.add_directive("pyramid_openapi3_spec", add_spec_view)
4343
config.add_directive("pyramid_openapi3_spec_directory", add_spec_view_directory)
4444
config.add_tween("pyramid_openapi3.tween.response_tween_factory", over=EXCVIEW)
45-
config.add_subscriber(check_all_routes, ApplicationCreated)
45+
config.add_subscriber(validate_routes, ApplicationCreated)
46+
config.add_subscriber(validate_minimal_responses, ApplicationCreated)
4647

4748
if not config.registry.settings.get( # pragma: no branch
4849
"pyramid_openapi3_extract_errors"
@@ -293,11 +294,11 @@ def openapi_validation_error(
293294
return exception_response(status_code, json_body=errors)
294295

295296

296-
def check_all_routes(event: ApplicationCreated):
297-
"""Assert all endpoints in the spec are registered as routes.
297+
def validate_routes(event: ApplicationCreated):
298+
"""Assert all endpoints in the spec have a route registered for them.
298299
299300
Listen for ApplicationCreated event and assert all endpoints defined in
300-
the API spec have been registered as Pyramid routes.
301+
the API spec have been assigned a Pyramid route.
301302
"""
302303

303304
app = event.app
@@ -313,7 +314,7 @@ def check_all_routes(event: ApplicationCreated):
313314
if not app.registry.settings.get(
314315
"pyramid_openapi3.enable_endpoint_validation", True
315316
):
316-
logger.info("Endpoint validation against specification is disabled")
317+
logger.info("Endpoint validation is disabled")
317318
return
318319

319320
# Sometimes api routes are prefixed with `/api/v1` and similar, using
@@ -338,3 +339,28 @@ def remove_prefixes(path):
338339
missing = [r for r in paths if r not in routes]
339340
if missing:
340341
raise MissingEndpointsError(missing)
342+
343+
344+
def validate_minimal_responses(event: ApplicationCreated):
345+
"""Assert all endpoints in the spec have defined at least minimal responses.
346+
347+
By default this makes sure that all endpoints have the minimal required
348+
responses defined in the spec: 200, 400 and 500
349+
350+
Additionally, all endpoints with parameters need to have 404 defined in the
351+
spec.
352+
353+
Finally, it is possible to override the minimal required responses for
354+
each endpoint by setting "pyramid_openapi3.endpoint_validation_overrides"
355+
to {'/endpoint/path': {'post': [202, 400, 500]}}
356+
"""
357+
app = event.app
358+
minimal_responses = app.registry.settings.get( # noqa
359+
"pyramid_openapi3.endpoint_validation_minimal_responses", [200, 400, 500]
360+
)
361+
minimal_responses_with_parameters = app.registry.settings.get( # noqa
362+
"pyramid_openapi3.endpoint_validation_minimal_responses_with_parameters", [404]
363+
)
364+
overrides = app.registry.settings.get( # noqa
365+
"pyramid_openapi3.endpoint_validation_overrides", [404]
366+
)

pyramid_openapi3/tests/test_app_construction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def test_disable_endpoint_validation(
139139

140140
app_config.make_wsgi_app()
141141

142-
assert "Endpoint validation against specification is disabled" in caplog.text
142+
assert "Endpoint validation is disabled" in caplog.text
143143

144144

145145
def test_unconfigured_app(

0 commit comments

Comments
 (0)