Beispiel #1
0
            async def awaitable(receive: Receive, send: Send) -> None:
                app = scope["app"]

                route, route_scope = app.router.get_route_from_scope(scope)

                state = {
                    "scope": scope,
                    "receive": receive,
                    "send": send,
                    "exc": None,
                    "app": app,
                    "path_params": route_scope["path_params"],
                    "route": route,
                    "request": http.Request(scope, receive),
                }

                injected_func = await app.injector.inject(endpoint, state)

                if asyncio.iscoroutinefunction(endpoint):
                    response = await injected_func()
                else:
                    response = await run_in_threadpool(injected_func)

                # Wrap response data with a proper response class
                if isinstance(response, (dict, list)):
                    response = APIResponse(content=response,
                                           schema=get_output_schema(endpoint))
                elif isinstance(response, str):
                    response = APIResponse(content=response)
                elif response is None:
                    response = APIResponse(content="")

                await response(receive, send)
Beispiel #2
0
    def test_render_no_schema(self):
        content = {"foo": "bar"}
        expected_result = {"foo": "bar"}

        response = APIResponse(content=content)

        assert json.loads(response.body.decode()) == expected_result
Beispiel #3
0
    def test_render_no_content(self):
        content = {}
        expected_result = b""

        response = APIResponse(content=content)

        assert response.body == expected_result
Beispiel #4
0
    def test_render_error(self, schema):
        content = {}
        expected_calls = [call(content)]
        schema.dump.side_effect = Exception

        with pytest.raises(SerializationError):
            APIResponse(schema=schema, content=content)

        assert schema.dump.call_args_list == expected_calls
Beispiel #5
0
    def test_render(self, schema):
        content = {"foo": "bar"}
        expected_calls = [call(content)]
        expected_result = {"foo": "bar"}
        schema.dump.return_value = content

        response = APIResponse(schema=schema, content=content)

        assert schema.dump.call_args_list == expected_calls
        assert json.loads(response.body.decode()) == expected_result
Beispiel #6
0
    async def dispatch(self) -> None:
        request = Request(self.scope, receive=self.receive)
        app = self.scope["app"]

        route, route_scope = app.router.get_route_from_scope(self.scope)

        state = {
            "scope": self.scope,
            "receive": self.receive,
            "send": self.send,
            "exc": None,
            "app": app,
            "path_params": route_scope["path_params"],
            "route": route,
            "request": request,
        }
        handler_name = "get" if request.method == "HEAD" else request.method.lower()
        handler = getattr(self, handler_name, self.method_not_allowed)

        injected_func = await app.injector.inject(handler, state)
        background_task = next(
            (v for k, v in state.items() if k.startswith('backgroundtasks:') and isinstance(v, BackgroundTask)),
            None
        )
        if asyncio.iscoroutinefunction(handler):
            response = await injected_func()
        else:
            response = await run_in_threadpool(injected_func)

        # Wrap response data with a proper response class
        if isinstance(response, (dict, list)):
            response = APIResponse(content=response, schema=get_output_schema(handler), background=background_task)
        elif isinstance(response, str):
            response = APIResponse(content=response, background=background_task)
        elif response is None:
            response = APIResponse(content="", background=background_task)
        elif not isinstance(response, Response):
            schema = get_output_schema(handler)
            if schema is not None:
                response = APIResponse(content=response, schema=get_output_schema(handler), background=background_task)

        await response(self.scope, self.receive, self.send)
Beispiel #7
0
        async def drop(self) -> DropCollection:
            query = sqlalchemy.select(
                [sqlalchemy.func.count(self.model.c[model.primary_key.name])])
            result = next(
                (i for i in (await self.database.fetch_one(query)).values()))

            query = self.model.delete()
            await self.database.execute(query)

            return APIResponse(schema=DropCollection(),
                               content={"deleted": result},
                               status_code=204)
Beispiel #8
0
    async def dispatch(self, request: Request, state: typing.Dict,
                       **kwargs) -> Response:
        handler_name = "get" if request.method == "HEAD" else request.method.lower(
        )
        handler = getattr(self, handler_name, self.method_not_allowed)

        app = state["app"]
        injected_func = await app.injector.inject(handler, state)
        if asyncio.iscoroutinefunction(handler):
            response = await injected_func()
        else:
            response = await run_in_threadpool(injected_func)

        # Wrap response data with a proper response class
        if isinstance(response, (dict, list)):
            response = APIResponse(content=response,
                                   schema=get_output_schema(handler))
        elif isinstance(response, str):
            response = APIResponse(content=response)
        elif response is None:
            response = APIResponse(content="")

        return response
Beispiel #9
0
        async def delete(self, element_id: model.primary_key.type):
            query = sqlalchemy.select([
                sqlalchemy.exists().where(
                    self.model.c[model.primary_key.name] == element_id)
            ])
            exists = next(
                (i for i in (await self.database.fetch_one(query)).values()))
            if not exists:
                raise HTTPException(status_code=404)

            query = self.model.delete().where(
                self.model.c[model.primary_key.name] == element_id)
            await self.database.execute(query)

            return APIResponse(status_code=204)
Beispiel #10
0
        async def _app(scope: Scope, receive: Receive, send: Send) -> None:
            app = scope["app"]

            route, route_scope = app.router.get_route_from_scope(scope)

            state = {
                "scope": scope,
                "receive": receive,
                "send": send,
                "exc": None,
                "app": app,
                "path_params": route_scope["path_params"],
                "route": route,
                "request": http.Request(scope, receive),
            }

            try:
                injected_func = await app.injector.inject(endpoint, state)
                background_task = next((v for k, v in state.items()
                                        if k.startswith('backgroundtasks:')
                                        and isinstance(v, BackgroundTask)),
                                       None)

                if asyncio.iscoroutinefunction(endpoint):
                    response = await injected_func()
                else:
                    response = await run_in_threadpool(injected_func)

                # Wrap response data with a proper response class
                if isinstance(response, (dict, list)):
                    response = APIResponse(
                        content=response,
                        schema=get_output_schema(endpoint),
                        background=background_task,
                        status_code=self.status_code,
                    )
                elif isinstance(response, str):
                    response = APIResponse(
                        content=response,
                        background=background_task,
                        status_code=self.status_code,
                    )
                elif response is None:
                    response = APIResponse(
                        content="",
                        background=background_task,
                        status_code=self.status_code,
                    )
                elif not isinstance(response, Response):
                    schema = get_output_schema(endpoint)
                    if schema is not None:
                        response = APIResponse(
                            content=response,
                            schema=get_output_schema(endpoint),
                            background=background_task,
                            status_code=self.status_code,
                        )
            except Exception:
                logger.exception("Error building response")
                raise

            await response(scope, receive, send)
Beispiel #11
0
 async def create(self, element: input_schema) -> output_schema:
     query = self.model.insert().values(**element)
     await self.database.execute(query)
     return APIResponse(schema=output_schema(),
                        content=element,
                        status_code=201)
Beispiel #12
0
    def test_init(self, schema):
        with patch("flama.responses.JSONResponse.__init__"):
            response = APIResponse(schema=schema)

        assert response.schema == schema