def __call__(self, environ, start_response):

        # create the request and response object
        req = self.request_cls(environ)
        resp = self.response_cls()
        state = RoutingState(req, resp, self)
        environ['pecan.locals'] = {
            'request': req,
            'response': resp
        }
        controller = None

        # handle the request
        try:
            # add context and environment to the request
            req.context = environ.get('pecan.recursive.context', {})
            req.pecan = dict(content_type=None)

            controller, args, kwargs = self.find_controller(state)
            self.invoke_controller(controller, args, kwargs, state)
        except Exception as e:
            # if this is an HTTP Exception, set it as the response
            if isinstance(e, exc.HTTPException):
                # if the client asked for JSON, do our best to provide it
                best_match = acceptparse.MIMEAccept(
                    getattr(req.accept, 'header_value', '*/*')
                ).best_match(('text/plain', 'text/html', 'application/json'))
                state.response = e
                if best_match == 'application/json':
                    json_body = dumps({
                        'code': e.status_int,
                        'title': e.title,
                        'description': e.detail
                    })
                    if isinstance(json_body, six.text_type):
                        e.text = json_body
                    else:
                        e.body = json_body
                    state.response.content_type = best_match
                environ['pecan.original_exception'] = e

            # if this is not an internal redirect, run error hooks
            on_error_result = None
            if not isinstance(e, ForwardRequestException):
                on_error_result = self.handle_hooks(
                    self.determine_hooks(state.controller),
                    'on_error',
                    state,
                    e
                )

            # if the on_error handler returned a Response, use it.
            if isinstance(on_error_result, WebObResponse):
                state.response = on_error_result
            else:
                if not isinstance(e, exc.HTTPException):
                    raise

            # if this is an HTTP 405, attempt to specify an Allow header
            if isinstance(e, exc.HTTPMethodNotAllowed) and controller:
                allowed_methods = _cfg(controller).get('allowed_methods', [])
                if allowed_methods:
                    state.response.allow = sorted(allowed_methods)
        finally:
            # handle "after" hooks
            self.handle_hooks(
                self.determine_hooks(state.controller), 'after', state
            )

        self._handle_empty_response_body(state)

        # get the response
        return state.response(environ, start_response)
Implements the WSGI specification for Pecan applications, utilizing
dataset/ETHPy150Open pecan/pecan/pecan/core.py/PecanBase.__call__