code: from typing import List
  
  from fastapi.responses import StreamingResponse
  from llama_index.chat_engine.types import BaseChatEngine
  
  from app.engine.index import get_chat_engine
  from fastapi import APIRouter, Depends, HTTPException, Request, status
  from llama_index.llms.base import ChatMessage
  from llama_index.llms.types import MessageRole
  from pydantic import BaseModel
  
  chat_router = r = APIRouter()
  
  
  class _Message(BaseModel):
      role: MessageRole
      content: str
  
  
  class _ChatData(BaseModel):
      messages: List[_Message]
  
  
  @r.post("")
  async def chat(
      request: Request,
      data: _ChatData,
      chat_engine: BaseChatEngine = Depends(get_chat_engine),
  ):
      # check preconditions and get last message
      if len(data.messages) == 0:
          raise HTTPException(
              status_code=status.HTTP_400_BAD_REQUEST,
              detail="No messages provided",
          )
      lastMessage = data.messages.pop()
      if lastMessage.role != MessageRole.USER:
          raise HTTPException(
              status_code=status.HTTP_400_BAD_REQUEST,
              detail="Last message must be from user",
          )
      # convert messages coming from the request to type ChatMessage
      messages = [
          ChatMessage(
              role=m.role,
              content=m.content,
          )
          for m in data.messages
      ]
  
      # query chat engine
      response = await chat_engine.astream_chat(lastMessage.content, messages)
  
      # stream response
      async def event_generator():
          async for token in response.async_response_gen():
              # If client closes connection, stop sending events
              if await request.is_disconnected():
                  break
              yield token
  
      return StreamingResponse(event_generator(), media_type="text/plain")
  
apis: llama_index.llms.base.ChatMessage
extract_api: [((390, 401), 'fastapi.APIRouter', 'APIRouter', ([], {}), '()\n', (399, 401), False, 'from fastapi import APIRouter, Depends, HTTPException, Request, status\n'), ((636, 660), 'fastapi.Depends', 'Depends', (['get_chat_engine'], {}), '(get_chat_engine)\n', (643, 660), False, 'from fastapi import APIRouter, Depends, HTTPException, Request, status\n'), ((758, 848), 'fastapi.HTTPException', 'HTTPException', ([], {'status_code': 'status.HTTP_400_BAD_REQUEST', 'detail': '"""No messages provided"""'}), "(status_code=status.HTTP_400_BAD_REQUEST, detail=\n    'No messages provided')\n", (771, 848), False, 'from fastapi import APIRouter, Depends, HTTPException, Request, status\n'), ((976, 1076), 'fastapi.HTTPException', 'HTTPException', ([], {'status_code': 'status.HTTP_400_BAD_REQUEST', 'detail': '"""Last message must be from user"""'}), "(status_code=status.HTTP_400_BAD_REQUEST, detail=\n    'Last message must be from user')\n", (989, 1076), False, 'from fastapi import APIRouter, Depends, HTTPException, Request, status\n'), ((1199, 1242), 'llama_index.llms.base.ChatMessage', 'ChatMessage', ([], {'role': 'm.role', 'content': 'm.content'}), '(role=m.role, content=m.content)\n', (1210, 1242), False, 'from llama_index.llms.base import ChatMessage\n')]