code: def perspective_thread(manager):
      """Perspective application thread starts its own tornado IOLoop, and
      adds the table with the name "data_source_one", which will be used
      in the front-end."""
      table = Table(
          {
              "name": str,
              "client": str,
              "open": float,
              "high": float,
              "low": float,
              "close": float,
              "lastUpdate": datetime,
              "date": date,
          },
          limit=2500,
      )
  
      # Track the table with the name "data_source_one", which will be used in
      # the front-end to access the Table.
      manager.host_table("data_source_one", table)
  
      # update with new data every 50ms
      def updater():
          table.update(data_source())
  
      callback = tornado.ioloop.PeriodicCallback(
          callback=updater, callback_time=50
      )
  
      psp_loop = tornado.ioloop.IOLoop()
      if IS_MULTI_THREADED:
          with concurrent.futures.ThreadPoolExecutor() as executor:
              manager.set_loop_callback(
                  psp_loop.run_in_executor, executor
              )
              callback.start()
              psp_loop.start()
      else:
          manager.set_loop_callback(psp_loop.add_callback)
          callback.start()
          psp_loop.start()
  
file_path: perspective/examples/python-tornado-streaming/server.py
imports: import random
  import logging
  import threading
  import tornado.websocket
  import tornado.web
  import tornado.ioloop
  from datetime import date, datetime
  from perspective import Table, PerspectiveManager, PerspectiveTornadoHandler
  import threading
  import concurrent.futures
label_desc: Use image node_id 2 for calling a global function with example usage: perspective_thread(manager) without return types