code: def make_app():
      manager = PerspectiveManager()
  
      thread = threading.Thread(
          target=perspective_thread, args=(manager,)
      )
      thread.daemon = True
      thread.start()
  
      async def websocket_handler(websocket: WebSocket):
          handler = PerspectiveStarletteHandler(
              manager=manager, websocket=websocket
          )
          await handler.run()
  
      # static_html_files = StaticFiles(directory="../python-tornado", html=True)
      static_html_files = StaticFiles(
          directory="../python-tornado", html=True
      )
  
      app = FastAPI()
      app.add_api_websocket_route("/websocket", websocket_handler)
      app.get("/node_modules/{rest_of_path:path}")(
          static_nodemodules_handler
      )
      app.mount("/", static_html_files)
  
      app.add_middleware(
          CORSMiddleware,
          allow_origins=["*"],
          allow_credentials=True,
          allow_methods=["*"],
          allow_headers=["*"],
      )
      return app
  
file_path: perspective/examples/python-starlette/server.py
imports: import asyncio
  import os
  import os.path
  import logging
  import threading
  import uvicorn
  from fastapi import FastAPI, WebSocket
  from fastapi.middleware.cors import CORSMiddleware
  from starlette.responses import FileResponse
  from starlette.staticfiles import StaticFiles
  from perspective import Table, PerspectiveManager, PerspectiveStarletteHandler
label_desc: Use image node_id 3 for calling a global function with example usage: make_app() and returns: app