コード例 #1
0
ファイル: test_delayed_view.py プロジェクト: podhmo/mokehehe
    def callView(self, config, path):
        from pyramid.router import Router
        from pyramid.testing import DummyRequest

        router = Router(config.registry)
        request = DummyRequest(path=path, registry=config.registry)
        return router.handle_request(request)
コード例 #2
0
ファイル: core.py プロジェクト: tomster/stasis
 def build(self):
     with main_module(self.site):
         self.registry.notify(PreBuild(self))
         paths = self.get_paths()
         router = Router(self.registry)
         extensions = self.registry.queryUtility(IRequestExtensions)
         for path in paths:
             request = _make_request(path, registry=self.registry)
             if extensions is not None:
                 request._set_extensions(extensions)
             response = router.handle_request(request)
             self.write(path, response)
コード例 #3
0
ファイル: test_viewobject.py プロジェクト: podhmo/mokehehe
    def callView(self, config, path, matchdict=None, GET=None, POST=None, iface=None):
        from pyramid.router import Router
        from pyramid.testing import DummyRequest

        router = Router(config.registry)
        request = DummyRequest(path=path, registry=config.registry)
        request.matchdict = matchdict or {}
        if GET:
            request.GET = GET
        if POST:
            request.POST = POST
        if iface:
            directlyProvides(request, iface)
        return router.handle_request(request)
コード例 #4
0
    def test_request_validation_error(self) -> None:
        """Request validation errors are rendered as 400 JSON responses."""
        self._add_view()
        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "HTTP_ACCEPT": "application/json",
        }
        start_response = DummyStartResponse()
        with self.assertLogs(level="INFO") as cm:
            response = router(environ, start_response)

        self.assertEqual(start_response.status, "400 Bad Request")
        self.assertEqual(
            json.loads(response[0]),
            [
                {
                    "exception": "MissingRequiredParameter",
                    "message": "Missing required parameter: bar",
                    "field": "bar",
                }
            ],
        )
        self.assertEqual(
            cm.output, ["INFO:pyramid_openapi3:Missing required parameter: bar"]
        )
コード例 #5
0
    def test_response_validation_error(self) -> None:
        """Test View raises ResponseValidationError.

        Example view raises an undefined response code.
        The response validation tween should catch this as response validation error,
        and return an error 500.
        """
        from pyramid.httpexceptions import HTTPPreconditionFailed

        self._add_view(lambda *arg:
                       (_ for _ in ()).throw(HTTPPreconditionFailed()))
        self._add_default_exception_view()
        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "HTTP_ACCEPT": "application/json",
            "QUERY_STRING": "bar=1",
        }
        start_response = DummyStartResponse()
        response = router(environ, start_response)
        self.assertEqual(start_response.status, "500 Internal Server Error")
        self.assertIn(
            "Unknown response http status: 412",
            json.loads(b"".join(response))["message"],
        )
コード例 #6
0
    def test_nonapi_view_exception(self) -> None:
        """Test View without openapi validation raises HTTPException.

        Example view raises a defined response code.
        """
        from pyramid.httpexceptions import HTTPBadRequest

        def view_func(*args):
            raise HTTPBadRequest("bad foo request")

        self._add_view(view_func, openapi=False)
        self._add_default_exception_view()
        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
        }
        start_response = DummyStartResponse()
        response = router(environ, start_response)
        self.assertEqual(start_response.status, "400 Bad Request")
        self.assertIn(b"foo", b"".join(response))
コード例 #7
0
    def test_no_default_exception_view(self) -> None:
        """Test Response Validation Error without default exception view.

        This causes the ResponseValidationError to bubble up to the top, because
        there is no view to render the HTTPException into a response.
        """
        from pyramid.httpexceptions import HTTPPreconditionFailed
        from pyramid_openapi3.exceptions import ResponseValidationError

        # return the exception, so that response validation can kick in
        self._add_view(lambda *arg: HTTPPreconditionFailed())
        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "QUERY_STRING": "bar=1",
        }
        start_response = DummyStartResponse()
        with self.assertRaises(ResponseValidationError) as cm:
            router(environ, start_response)
        self.assertEqual(cm.exception.status_code, 500)
        self.assertEqual("Unknown response http status: 412",
                         str(cm.exception))
コード例 #8
0
ファイル: core.py プロジェクト: fschulze/stasis
 def build(self):
     with main_module(self.site):
         __import__("__main__.config")
         config = self.site.config.config
         self.registry = config.registry
         config.add_request_method(static_path)
         config.add_request_method(relroute_path)
         config.commit()
         self.registry['path'] = self.path
         self.siteconfig = config.registry.queryUtility(
             IConfigFactory,
             default=DefaultConfigFactory)(self.registry)
         self.siteconfig.setdefault('site', {})
         self.siteconfig['site'].setdefault('outpath', 'output')
         self.registry['root'] = config.registry.queryUtility(IRootFactory)
         self.registry['siteconfig'] = self.siteconfig
         self.registry.registerUtility(lambda h, r: h, ITweens)
         written_paths = set()
         self.registry.notify(PreBuild(self))
         paths = self.get_paths()
         router = Router(self.registry)
         extensions = self.registry.queryUtility(IRequestExtensions)
         for path in paths:
             request = _make_request(path, registry=self.registry)
             self.threadlocal_manager.push(dict(
                 registry=self.registry, request=request))
             try:
                 if extensions is not None:
                     request._set_extensions(extensions)
                 response = router.handle_request(request)
             finally:
                 self.threadlocal_manager.pop()
             written_paths.add(self.write(path[1:], response))
         all_paths = dirtools.Dir(self.siteconfig['site']['outpath'])
         for path in set(all_paths.files()).difference(written_paths):
             fn = os.path.join(self.siteconfig['site']['outpath'], path)
             log.info("Deleting '%s'." % path)
             os.unlink(fn)
         for path in all_paths.subdirs(sort_reverse=True):
             fn = os.path.join(self.siteconfig['site']['outpath'], path)
             try:
                 os.rmdir(fn)
                 log.info("Removed '%s'." % path)
             except OSError as ex:
                 if ex.errno != errno.ENOTEMPTY:
                     raise
コード例 #9
0
    def test_request_validation_error_causes_response_validation_error(self) -> None:
        """Tests fallback for when request validation is disallowed by the spec.

        When a request fails validation an exception is raised which causes
        a 400 error to be raised to the end user specifying what the problem was.
        If the API spec disallows 400 errors, this will be transformed into a
        500 error with a response validation message about incorrect types.

        We should also raise a warning in this case, so developers are alerted to
        such problems.
        """
        self._add_view()
        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "HTTP_ACCEPT": "application/json",
            "QUERY_STRING": "unknown=1",
        }
        start_response = DummyStartResponse()
        with self.assertLogs(level="ERROR") as cm:
            with warnings.catch_warnings(record=True) as cw:
                response = router(environ, start_response)
                self.assertEqual(len(cw), 1)
                self.assertEqual(
                    str(cw[0].message),
                    'Discarding 400 Bad Request validation error with body [{"exception":"MissingRequiredParameter","message":"Missing required parameter: bar","field":"bar"}] as it is not a valid response for GET to /foo (foo)',
                )
        self.assertEqual(
            cm.output, ["ERROR:pyramid_openapi3:Unknown response http status: 400"]
        )

        self.assertEqual(start_response.status, "500 Internal Server Error")
        if openapi_core.__version__ == "0.13.8":  # pragma: no cover
            self.assertEqual(
                json.loads(response[0]),
                [
                    {
                        "exception": "ResponseNotFound",
                        "message": "Unknown response http status: 400",
                    }
                ],
            )
        else:  # pragma: no cover
            self.assertEqual(
                json.loads(response[0]),
                [
                    {
                        "exception": "InvalidResponse",
                        "message": "Unknown response http status: 400",
                    }
                ],
            )
コード例 #10
0
def test_add_spec_view_directory() -> None:
    """Test registration of a view that serves the openapi document."""
    with testConfig() as config:
        config.include("pyramid_openapi3")

        with tempfile.TemporaryDirectory() as directory:
            spec_name = os.path.join(directory, "openapi.yaml")
            spec_paths_name = os.path.join(directory, "paths.yaml")
            with open(spec_name, "wb") as f:
                f.write(SPLIT_DOCUMENT)
            with open(spec_paths_name, "wb") as f:
                f.write(SPLIT_DOCUMENT_PATHS)

            config.pyramid_openapi3_spec_directory(spec_name,
                                                   route="/foo",
                                                   route_name="foo_api_spec")

            # assert settings
            openapi_settings = config.registry.settings["pyramid_openapi3"]
            assert openapi_settings["filepath"] == spec_name
            assert openapi_settings["spec_route_name"] == "foo_api_spec"
            assert openapi_settings["spec"].info.title == "Foo API"
            assert "get" in openapi_settings["spec"].paths["/foo"].operations
            assert isinstance(openapi_settings["request_validator"],
                              RequestValidator)
            assert isinstance(openapi_settings["response_validator"],
                              ResponseValidator)

            # assert route
            # routes[0] is the static view, routes[1] is the route
            mapper = config.registry.getUtility(IRoutesMapper)
            routes = mapper.get_routes()
            assert routes[0].name == "__/foo/"
            assert routes[0].path == "/foo/*subpath"
            assert routes[1].name == "foo_api_spec"
            assert routes[1].path == "/foo/openapi.yaml"

            # assert view
            route_request = config.registry.queryUtility(IRouteRequest,
                                                         name="foo_api_spec")
            static_request = config.registry.queryUtility(IRouteRequest,
                                                          name="__/foo/")
            view = config.registry.adapters.registered(
                (IViewClassifier, static_request, Interface), IView, name="")
            assert route_request is not None
            assert static_request is not None
            assert view is not None

            # assert router
            router = Router(config.registry)
            response = router({"PATH_INFO": "/foo/openapi.yaml"},
                              DummyStartResponse())
            assert next(response) == SPLIT_DOCUMENT
            response = router({"PATH_INFO": "/foo/paths.yaml"},
                              DummyStartResponse())
            assert next(response) == SPLIT_DOCUMENT_PATHS
コード例 #11
0
    def build_traverse_trees(self):
        """Build all traversed hierarchies."""
        mapper = self.get_mapper()
        router = Router(self.request.registry)

        routes = mapper.get_routes(include_static=False)

        for route in routes:
            if not self.is_traversable_sitemap_route(route):
                continue

            root_context = self.get_traverse_endpoint_context(router, route)
            self.recurse_traversable(router, route, root_context)
コード例 #12
0
    def test_response_validation_error(self) -> None:
        """Test View raises ResponseValidationError.

        Example view raises an undefined response code.
        The response validation tween should catch this as response validation error,
        and return an error 500.
        """
        from pyramid.httpexceptions import HTTPPreconditionFailed

        self._add_view(lambda *arg: HTTPPreconditionFailed())

        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "HTTP_ACCEPT": "application/json",
            "QUERY_STRING": "bar=1",
        }
        start_response = DummyStartResponse()
        with self.assertLogs(level="ERROR") as cm:
            response = router(environ, start_response)
        self.assertEqual(start_response.status, "500 Internal Server Error")
        if openapi_core.__version__ == "0.13.8":  # pragma: no cover
            self.assertEqual(
                json.loads(response[0]),
                [
                    {
                        "exception": "ResponseNotFound",
                        "message": "Unknown response http status: 412",
                    }
                ],
            )
        else:  # pragma: no cover
            self.assertEqual(
                json.loads(response[0]),
                [
                    {
                        "exception": "InvalidResponse",
                        "message": "Unknown response http status: 412",
                    }
                ],
            )
        self.assertEqual(
            cm.output, ["ERROR:pyramid_openapi3:Unknown response http status: 412"]
        )
コード例 #13
0
 def test_nonapi_view(self) -> None:
     """Test View without openapi validation."""
     self._add_view(openapi=False)
     # run request through router
     router = Router(self.config.registry)
     environ = {
         "wsgi.url_scheme": "http",
         "SERVER_NAME": "localhost",
         "SERVER_PORT": "8080",
         "REQUEST_METHOD": "GET",
         "PATH_INFO": "/foo",
     }
     start_response = DummyStartResponse()
     response = router(environ, start_response)
     self.assertEqual(start_response.status, "200 OK")
     self.assertIn(b"foo", b"".join(response))
コード例 #14
0
 def test_view_valid_request_response(self) -> None:
     """Test openapi validated view which has correct request and response."""
     self._add_view(lambda *arg: {"test": "correct"})
     # run request through router
     router = Router(self.config.registry)
     environ = {
         "wsgi.url_scheme": "http",
         "SERVER_NAME": "localhost",
         "SERVER_PORT": "8080",
         "REQUEST_METHOD": "GET",
         "PATH_INFO": "/foo",
         "HTTP_ACCEPT": "application/json",
         "QUERY_STRING": "bar=1",
     }
     start_response = DummyStartResponse()
     response = router(environ, start_response)
     self.assertEqual(start_response.status, "200 OK")
     self.assertEqual(json.loads(response[0]), {"test": "correct"})
コード例 #15
0
    def test_tween_factory_can_find_api_factory(self):
        registry = self.config.registry
        router = Router(registry)

        # This palaver is necessary to call the tween directly.
        def _make_request(**environ):
            req = make_request(**environ)
            req.__dict__["request_iface"] = IRequest
            req.__dict__["registry"] = registry
            return req

        # Create the factory with no IAPIFactory registered.
        # It should grab the api from the request environ.
        registry.registerUtility(None, IAPIFactory)
        tween = whoauth_tween_factory(router.handle_request, registry)
        req = _make_request(PATH_INFO="/ok",
                            HTTP_AUTHORIZATION=GOOD_AUTHZ["test"])
        response = tween(req)
        self.assertHeadersContain(response.headerlist, "X-Dummy-Remember")
コード例 #16
0
    def test_default_exception_view(self) -> None:
        """Test Pyramid default exception response view.

        Pyramid default exception response view renders a RequestValidationError.
        """
        self._add_view()
        self._add_default_exception_view()
        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "HTTP_ACCEPT": "application/json",
        }
        start_response = DummyStartResponse()
        response = router(environ, start_response)
        self.assertEqual(start_response.status, "400 Bad Request")
        self.assertIn("Missing required parameter: bar",
                      json.loads(b"".join(response))["message"])
コード例 #17
0
    def test_response_validation_disabled(self) -> None:
        """Test View with response validation disabled."""
        self.config.registry.settings[
            "pyramid_openapi3.enable_response_validation"
        ] = False
        self._add_view(lambda *arg: "not-valid")

        # run request through router
        router = Router(self.config.registry)
        environ = {
            "wsgi.url_scheme": "http",
            "SERVER_NAME": "localhost",
            "SERVER_PORT": "8080",
            "REQUEST_METHOD": "GET",
            "PATH_INFO": "/foo",
            "HTTP_ACCEPT": "application/json",
            "QUERY_STRING": "bar=1",
        }
        start_response = DummyStartResponse()
        response = router(environ, start_response)
        self.assertEqual(start_response.status, "200 OK")
        self.assertIn(b'"not-valid"', response)
コード例 #18
0
    def make_wsgi_app(self):
        """ Commits any pending configuration statements, sends a
        :class:`pyramid.events.ApplicationCreated` event to all listeners,
        adds this configuration's registry to
        :attr:`pyramid.config.global_registries`, and returns a
        :app:`Pyramid` WSGI application representing the committed
        configuration state."""
        self.commit()
        app = Router(self.registry)

        # Allow tools like "pshell development.ini" to find the 'last'
        # registry configured.
        global_registries.add(self.registry)

        # Push the registry on to the stack in case any code that depends on
        # the registry threadlocal APIs used in listeners subscribed to the
        # IApplicationCreated event.
        self.manager.push({'registry': self.registry, 'request': None})
        try:
            self.registry.notify(ApplicationCreated(app))
        finally:
            self.manager.pop()

        return app
コード例 #19
0
def _makeRouter(config):
    from pyramid.router import Router
    router = Router(config.registry)
    return router
コード例 #20
0
 def make_wsgi_app(self):  # pragma: no cover
     self.commit()
     global_registries.add(self.registry)
     return Router(self.registry)
コード例 #21
0
ファイル: __init__.py プロジェクト: andantic/adhocracy3
def get_root(app: Router):
    """Return the root of the application."""
    request = Request.blank('/path-is-meaningless-here')
    request.registry = app.registry
    root = app.root_factory(request)
    return root
コード例 #22
0
ファイル: __init__.py プロジェクト: andantic/adhocracy3
def get_root(app: Router):
    """Return the root of the application."""
    request = Request.blank('/path-is-meaningless-here')
    request.registry = app.registry
    root = app.root_factory(request)
    return root