1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
# Create anonymous function that we can later call to get all needed python
# metdata for the manifest
pythonConfigurator <- function(python,
forceGenerate = FALSE) {
if (is.null(python)) {
return(NULL)
}
force(forceGenerate)
function(appDir) {
withCallingHandlers(
inferPythonEnv(
appDir,
python = python,
forceGenerate = forceGenerate
),
error = function(err) {
cli::cli_abort(
"Failed to detect python environment",
parent = err
)
}
)
}
}
# python is enabled on Connect and posit.cloud, but not on Shinyapps
getPythonForTarget <- function(path, accountDetails) {
targetIsShinyapps <- isShinyappsServer(accountDetails$server)
pythonEnabled <- getOption("rsconnect.python.enabled", !targetIsShinyapps)
if (pythonEnabled) {
getPython(path)
} else {
NULL
}
}
getPython <- function(path = NULL) {
if (!is.null(path)) {
return(path.expand(path))
}
path <- Sys.getenv("RETICULATE_PYTHON")
if (path != "") {
return(path.expand(path))
}
path <- Sys.getenv("RETICULATE_PYTHON_FALLBACK")
if (path != "") {
return(path.expand(path))
}
NULL
}
inferPythonEnv <- function(workdir,
python = getPython(),
forceGenerate = FALSE) {
# run the python introspection script
env_py <- system.file("resources/environment.py", package = "rsconnect")
args <- c(
shQuote(env_py),
if (forceGenerate) "-f",
shQuote(workdir)
)
hasConda <- is_installed("reticulate") &&
reticulate::py_available(initialize = FALSE) &&
reticulate::py_config()$anaconda
if (hasConda) {
prefix <- getCondaEnvPrefix(python)
conda <- getCondaExeForPrefix(prefix)
args <- c("run", "-p", prefix, python, args)
# conda run -p <prefix> python inst/resources/environment.py <flags> <dir>
output <- system2(command = conda, args = args, stdout = TRUE, stderr = NULL, wait = TRUE)
} else {
output <- system2(command = python, args = args, stdout = TRUE, stderr = NULL, wait = TRUE)
}
environment <- jsonlite::fromJSON(output)
if (is.null(environment$error)) {
list(
version = environment$python,
package_manager = list(
name = environment$package_manager,
version = environment[[environment$package_manager]],
package_file = environment$filename,
contents = environment$contents
)
)
} else {
cli::cli_abort(environment$error)
}
}
getCondaEnvPrefix <- function(python) {
prefix <- dirname(dirname(python))
if (!file.exists(file.path(prefix, "conda-meta"))) {
stop(paste("Python from", python, "does not look like a conda environment: cannot find `conda-meta`"))
}
prefix
}
getCondaExeForPrefix <- function(prefix) {
miniconda <- dirname(dirname(prefix))
conda <- file.path(miniconda, "bin", "conda")
if (isWindows()) {
conda <- paste(conda, ".exe", sep = "")
}
if (!file.exists(conda)) {
stop(paste("Conda env prefix", prefix, "does not have the `conda` command line interface."))
}
conda
}
|