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)
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
def test_render_no_content(self): content = {} expected_result = b"" response = APIResponse(content=content) assert response.body == expected_result
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
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
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)
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)
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
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)
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)
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)
def test_init(self, schema): with patch("flama.responses.JSONResponse.__init__"): response = APIResponse(schema=schema) assert response.schema == schema