Start the server with subprocess and julia.
(self, app, start_timeout=30, cwd=None)
| 468 | |
| 469 | # pylint: disable=arguments-differ |
| 470 | def start(self, app, start_timeout=30, cwd=None): # type: ignore[reportIncompatibleMethodOverride] |
| 471 | """Start the server with subprocess and julia.""" |
| 472 | |
| 473 | if os.path.isfile(app) and os.path.exists(app): |
| 474 | # app is already a file in a dir - use that as cwd |
| 475 | if not cwd: |
| 476 | cwd = os.path.dirname(app) |
| 477 | logger.info("JuliaRunner inferred cwd from app path: %s", cwd) |
| 478 | else: |
| 479 | # app is a string chunk, we make a temporary folder to store app.jl |
| 480 | # and its relevant assets |
| 481 | tmp_dir = "/tmp" if not self.is_windows else os.getenv("TEMP") |
| 482 | assert isinstance(tmp_dir, str) # to satisfy typing |
| 483 | hex_id = uuid.uuid4().hex |
| 484 | self._tmp_app_path = os.path.join(tmp_dir, hex_id) |
| 485 | assert isinstance(self.tmp_app_path, str) # to satisfy typing |
| 486 | try: |
| 487 | os.mkdir(self.tmp_app_path) |
| 488 | except OSError: |
| 489 | logger.exception("cannot make temporary folder %s", self.tmp_app_path) |
| 490 | path = os.path.join(self.tmp_app_path, "app.jl") |
| 491 | |
| 492 | logger.info("JuliaRunner start => app is Julia code chunk") |
| 493 | logger.info("make a temporary Julia file for execution => %s", path) |
| 494 | logger.debug("content of the Dash.jl app") |
| 495 | logger.debug("%s", app) |
| 496 | |
| 497 | with open(path, "w", encoding="utf-8") as fp: |
| 498 | fp.write(app) |
| 499 | |
| 500 | app = path |
| 501 | |
| 502 | # try to find the path to the calling script to use as cwd |
| 503 | if not cwd: |
| 504 | for entry in inspect.stack(): |
| 505 | if "/dash/testing/" not in entry[1].replace("\\", "/"): |
| 506 | cwd = os.path.dirname(os.path.realpath(entry[1])) |
| 507 | logger.warning("get cwd from inspect => %s", cwd) |
| 508 | break |
| 509 | if cwd: |
| 510 | logger.info( |
| 511 | "JuliaRunner inferred cwd from the Python call stack: %s", cwd |
| 512 | ) |
| 513 | |
| 514 | # try copying all valid sub folders (i.e. assets) in cwd to tmp |
| 515 | # note that the R assets folder name can be any valid folder name |
| 516 | assets = [ |
| 517 | os.path.join(cwd, _) |
| 518 | for _ in os.listdir(cwd) |
| 519 | if not _.startswith("__") and os.path.isdir(os.path.join(cwd, _)) |
| 520 | ] |
| 521 | |
| 522 | for asset in assets: |
| 523 | target = os.path.join(self.tmp_app_path, os.path.basename(asset)) |
| 524 | if os.path.exists(target): |
| 525 | logger.debug("delete existing target %s", target) |
| 526 | shutil.rmtree(target) |
| 527 | logger.debug("copying %s => %s", asset, self.tmp_app_path) |
nothing calls this directly
no test coverage detected