-
Notifications
You must be signed in to change notification settings - Fork 47
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
Integration with traversal #31
Comments
I've only lived in the URL dispatch world for the last ~5 years, and wouldn't know how to even being. Can you provide a basic example and I can then make it pretty, add tests, etc. |
The pyramid-cookiecutter-starter and related tutorial might be helpful. |
Hi there is a code example: import os
import random
from pyramid.config import Configurator
from pyramid.httpexceptions import HTTPNotImplemented
from pyramid.interfaces import ILocation
from pyramid.router import Router
from zope.interface import implementer
from zope.interface import Interface
from wsgiref.simple_server import make_server
class IGETView(Interface):
pass
class IPOSTView(Interface):
pass
class GETView:
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self):
return self.context.GET()
class POSTView:
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self):
return self.context.POST()
@implementer(ILocation, IGETView, IPOSTView)
class TraversalRoot:
def __init__(self, name, parent, request):
self.__name__ = name
self.__parent__ = parent
self.__request__ = request
def GET(self):
raise HTTPNotImplemented()
def POST(self):
raise HTTPNotImplemented()
class Hello(TraversalRoot):
def GET(self):
return {"msg": "hello world"}
class Bad_Hello(TraversalRoot):
def GET(self):
return {"bad_field": "hello world"}
class Root(TraversalRoot):
def __getitem__(self, name):
if name == "hello":
return Hello(name=name, parent=self, request=self.__request__)
if name == "bad_hello":
return Bad_Hello(name=name, parent=self, request=self.__request__)
raise KeyError
def POST(self):
data = self.__request__.json_body
content = data.get('content', None)
if content is None or content == '':
response = self.__request__.response
response.status_code = 400
response.content_type = "application/json"
response.charset = "utf-8"
response.json_body = {
"field": "content",
"message": "content field is required and can't be an empty string",
"exception": "ValidationError"
}
return response
toRet = {
"ID": random.randint(1,100),
"content" : data.get('content'),
"comments": data.get('comments', 'NO_COMMENT_SEND')
}
return toRet
def api_factory(request):
return Root(name="", parent=None, request=request)
def app() -> Router:
"""Prepare a Pyramid app."""
with Configurator(root_factory=api_factory) as config:
config.registry.settings["pyramid_openapi3.enable_endpoint_validation"] = False
# config.registry.settings["pyramid_openapi3.enable_request_validation"] = False
# config.registry.settings["pyramid_openapi3.enable_response_validation"] = False
config.include("pyramid_openapi3")
config.pyramid_openapi3_spec(
os.path.join(os.path.dirname(__file__), "openapi.yaml"),
)
config.pyramid_openapi3_add_explorer()
config.add_view(
GETView,
context=IGETView,
request_method="GET",
permission="read",
name="",
attr=None,
renderer="json",
openapi=True
)
config.add_view(
POSTView,
context=IPOSTView,
request_method="POST",
permission="create",
name="",
attr=None,
renderer="json",
openapi=True
)
return config.make_wsgi_app()
if __name__ == "__main__":
"""If app.py is called directly, start up the app."""
print("Swagger UI available at http://127.0.0.1:6543/docs/") # noqa: T001
server = make_server("127.0.0.1", 6543, app())
server.serve_forever() and the openapi.yaml openapi: "3.0.0"
info:
version: "1.0.0"
title: Example traversal api
paths:
/:
post:
summary: Fake create message
requestBody:
required: true
description: Data for creating a fake message
content:
application/json:
schema:
type: object
$ref: '#/components/schemas/CreateMessage'
responses:
'200':
description: Success message.
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/Message"
'400':
$ref: '#/components/responses/ValidationError'
/hello:
get:
summary: Hello Word route
responses:
'200':
description: Display Hello Word message
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/Hello"
/bad_hello:
get:
summary: Hello Word route failed response validation
responses:
'200':
description: failed response validation
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/Hello"
components:
schemas:
Hello:
type: object
required:
- msg
properties:
msg:
type: string
maxLength: 40
CreateMessage:
type: object
required:
- content
properties:
content:
type: string
comments:
type: string
Message:
type: object
required:
- ID
- content
properties:
ID:
type: integer
content:
type: string
comments:
type: string
Error:
type: object
required:
- message
properties:
field:
type: string
message:
type: string
exception:
type: string
responses:
ValidationError:
description: OpenAPI request/response validation failed
content:
application/json:
schema:
type: object
items:
$ref: "#/components/schemas/Error" As you can see in the App method If we activate it, pyramid_openapi raise a MissingEndpointsError in check_all_routes method but we have no route declared in pyramid when use traversal right ? we can activate pyramid_openapi3.enable_request_validation and pyramid_openapi3.enable_response_validation but: So is it working for traversal and i missing something in my understanding of how to implements it or it's an issue ? |
Looks like some work is needed before it works with traversal out-of-the-box, but your examples shows that it should be possible. |
Ok, Thanks for the answer |
All examples and documentation focus on URL dispatch, it would be good to support Traversal too or at least provide an example on how integrate pyramid_openapi3 in a Traversal only application
The text was updated successfully, but these errors were encountered: