Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add register_routes #121

Merged
merged 2 commits into from
Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,33 @@ config.registry.settings["pyramid_openapi3.enable_response_validation"] = False
> **Warning:**
Disabling request validation will result in `request.openapi_validated` no longer being available to use.

### Register Pyramid's Routes

You can register routes in your pyramid application.
First, write the `x-pyramid-route-name` extension in the PathItem of the OpenAPI schema.

```yaml
paths:
/foo:
x-pyramid-route-name: foo_route
get:
responses:
200:
description: GET foo
```

Then put the config directive `pyramid_openapi3_register_routes` in the app_factory of your application.

```python
config.pyramid_openapi3_register_routes()
```

This means is equals to

```python
config.add_route("foo_route", pattern="/foo")
```

## Demo / Examples

There are three examples provided with this package:
Expand Down
29 changes: 29 additions & 0 deletions pyramid_openapi3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from pathlib import Path
from pyramid.config import Configurator
from pyramid.config import PHASE0_CONFIG
from pyramid.config import PHASE1_CONFIG
from pyramid.config.views import ViewDeriverInfo
from pyramid.events import ApplicationCreated
from pyramid.exceptions import ConfigurationError
Expand Down Expand Up @@ -45,6 +46,7 @@ def includeme(config: Configurator) -> None:
config.add_directive("pyramid_openapi3_add_explorer", add_explorer_view)
config.add_directive("pyramid_openapi3_spec", add_spec_view)
config.add_directive("pyramid_openapi3_spec_directory", add_spec_view_directory)
config.add_directive("pyramid_openapi3_register_routes", register_routes)
config.add_tween("pyramid_openapi3.tween.response_tween_factory", over=EXCVIEW)
config.add_subscriber(check_all_routes, ApplicationCreated)

Expand Down Expand Up @@ -284,6 +286,33 @@ def register() -> None:
config.action(("pyramid_openapi3_spec",), register, order=PHASE0_CONFIG)


def register_routes(
config: Configurator,
route_name_ext: str = "x-pyramid-route-name",
root_factory_ext: str = "x-pyramid-root-factory",
apiname: str = "pyramid_openapi3",
) -> None:
"""Register routes to app from OpenApi 3.0 specification.

:param route_name_ext: Extension's key for using a ``route_name`` argument
:param root_factory_ext: Extension's key for using a ``factory`` argument
"""

def action() -> None:
spec = config.registry.settings[apiname]["spec"]
for pattern, path_item in spec.paths.items():
route_name = path_item.extensions.get(route_name_ext)
if route_name:
root_factory = path_item.extensions.get(root_factory_ext)
config.add_route(
route_name.value,
pattern=pattern,
factory=root_factory.value if root_factory else None,
)

config.action(("pyramid_openapi3_register_routes",), action, order=PHASE1_CONFIG)


def openapi_validation_error(
context: t.Union[RequestValidationError, ResponseValidationError], request: Request
) -> Response:
Expand Down
70 changes: 70 additions & 0 deletions pyramid_openapi3/tests/test_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Tests routes."""

from pyramid.request import Request
from pyramid.testing import testConfig

import tempfile


def dummy_factory(request: Request) -> str:
"""Root factory for testing."""
return "_DUMMY_" # pragma: no cover


def test_register_routes_simple() -> None:
"""Test registration routes without root_factory."""
with testConfig() as config:
config.include("pyramid_openapi3")
with tempfile.NamedTemporaryFile() as tempdoc:
tempdoc.write(
b"""\
openapi: "3.0.0"
info:
version: "1.0.0"
title: Foo API
paths:
/foo:
x-pyramid-route-name: foo
get:
responses:
200:
description: A foo
/bar:
get:
responses:
200:
description: A bar
"""
)
tempdoc.seek(0)
config.pyramid_openapi3_spec(tempdoc.name)
config.pyramid_openapi3_register_routes()
config.add_route("bar", "/bar")
config.make_wsgi_app()


def test_register_routes_with_factory() -> None:
"""Test registration routes with root_factory."""
with testConfig() as config:
config.include("pyramid_openapi3")
with tempfile.NamedTemporaryFile() as tempdoc:
tempdoc.write(
b"""\
openapi: "3.0.0"
info:
version: "1.0.0"
title: Foo API
paths:
/foo:
x-pyramid-route-name: foo
x-pyramid-root-factory: pyramid_openapi3.tests.test_routes.dummy_factory
get:
responses:
200:
description: A foo
"""
)
tempdoc.seek(0)
config.pyramid_openapi3_spec(tempdoc.name)
config.pyramid_openapi3_register_routes()
config.make_wsgi_app()