docstr: Start the server with subprocess and julia.
docstr_tok: ["Start","the","server","with","subprocess","and","julia","."]
code: def start(self, app, start_timeout=30, cwd=None):
      """Start the server with subprocess and julia."""
  
      if os.path.isfile(app) and os.path.exists(app):
          # app is already a file in a dir - use that as cwd
          if not cwd:
              cwd = os.path.dirname(app)
              logger.info(
                  "JuliaRunner inferred cwd from app path: %s", cwd
              )
      else:
          # app is a string chunk, we make a temporary folder to store app.jl
          # and its relevant assets
          self._tmp_app_path = os.path.join(
              "/tmp" if not self.is_windows else os.getenv("TEMP"),
              uuid.uuid4().hex,
          )
          try:
              os.mkdir(self.tmp_app_path)
          except OSError:
              logger.exception(
                  "cannot make temporary folder %s", self.tmp_app_path
              )
          path = os.path.join(self.tmp_app_path, "app.jl")
  
          logger.info("JuliaRunner start => app is Julia code chunk")
          logger.info(
              "make a temporary Julia file for execution => %s", path
          )
          logger.debug("content of the Dash.jl app")
          logger.debug("%s", app)
  
          with open(path, "w", encoding="utf-8") as fp:
              fp.write(app)
  
          app = path
  
          # try to find the path to the calling script to use as cwd
          if not cwd:
              for entry in inspect.stack():
                  if "/dash/testing/" not in entry[1].replace(
                      "\\", "/"
                  ):
                      cwd = os.path.dirname(os.path.realpath(entry[1]))
                      logger.warning("get cwd from inspect => %s", cwd)
                      break
          if cwd:
              logger.info(
                  "JuliaRunner inferred cwd from the Python call stack: %s",
                  cwd,
              )
  
              # try copying all valid sub folders (i.e. assets) in cwd to tmp
              # note that the R assets folder name can be any valid folder name
              assets = [
                  os.path.join(cwd, _)
                  for _ in os.listdir(cwd)
                  if not _.startswith("__")
                  and os.path.isdir(os.path.join(cwd, _))
              ]
  
              for asset in assets:
                  target = os.path.join(
                      self.tmp_app_path, os.path.basename(asset)
                  )
                  if os.path.exists(target):
                      logger.debug("delete existing target %s", target)
                      shutil.rmtree(target)
                  logger.debug(
                      "copying %s => %s", asset, self.tmp_app_path
                  )
                  shutil.copytree(asset, target)
                  logger.debug("copied with %s", os.listdir(target))
  
          else:
              logger.warning(
                  "JuliaRunner found no cwd in the Python call stack. "
                  "You may wish to specify an explicit working directory "
                  "using something like: "
                  "dashjl.run_server(app, cwd=os.path.dirname(__file__))"
              )
  
      logger.info("Run Dash.jl app with julia => %s", app)
  
      args = shlex.split(
          f"julia --project {os.path.realpath(app)}",
          posix=not self.is_windows,
      )
      logger.debug("start Dash.jl process with %s", args)
  
      try:
          self.proc = (
              subprocess.Popen(  # pylint: disable=consider-using-with
                  args,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  cwd=self.tmp_app_path if self.tmp_app_path else cwd,
              )
          )
          # wait until server is able to answer http request
          wait.until(
              lambda: self.accessible(self.url), timeout=start_timeout
          )
  
      except (OSError, ValueError):
          logger.exception("process server has encountered an error")
          self.started = False
          return
  
      self.started = True
  
imports: import sys
  import os
  import time
  import uuid
  import shlex
  import threading
  import shutil
  import subprocess
  import logging
  import inspect
  import ctypes
  import runpy
  import requests
  import psutil
  import multiprocess
  from dash.testing.errors import NoAppFoundError, TestingTimeoutError, ServerCloseError, DashAppLoadingError
  from dash.testing import wait
label_desc: Use image node_id 2 for calling the JuliaRunner obj's underlying member method code with example usage: obj.start(app, start_timeout, cwd) without return types