Getting the path of an external library in an R package that depends on that library

I'm making an R interface to a python library hosted on a server in my company. I'm wondering what's the recommended way to get the path of the python library programmatically to ensure the app keeps working independently of the location of the library.

1 Like

If you are expecting the user to be able to manage their own Python installation manually, you could use Sys.which("python") to find their Python installation.

However, if you are using {reticulate} to manage the Python setup for the user, then you should follow their guidance (which has recently changed now that as of {reticulate} 1.42.0 they are instead encouraging the use of uv for all Python installations).

1 Like

Thank you for the suggestions.

In fact, we were hoping to run it on the server as well (supposing that's actually possible). Currently, I'm making the interface as an R package but the end goal is to implement the tools in a shiny app since the end users won't have much coding experience. The actual tools are quite computer intensive (deep sequencing analyses of PCR amplicons), ideally we would like to install it on the server that has an access to a super computer.

I was looking at the quarto and keras3 R packages earlier today since the interface is quite similar to what I'm building. keras3 has a more sophisticated architecture and uses reticulate which I'm not very familiar with but piqued my curiosity. Both of those packages are intended to be ran locally though.

Would reticulate or uv be a solution in my case?

1 Like

It's hard to give specific advice without knowing more about how your R package functions need to use Python.

In general, if you want to be able to call many different functions from the Python package, then it would make sense to use {reticulate}. In other words, {reticulate} allows R code to run Python functions as if they were R functions. However, if you just need to shell out to Python a few times, integrating via {reticulate} may be overkill.

Another advantage you have is that your end users will be using your package interactively via a Shiny App. In that case, you only have to be concerned with how you and other developers install Python on the production server and for local development. Thus you could use whatever you want to install Python (APT, conda, uv, etc) as long as you document it for other developers.

1 Like

Thanks a lot for this. I guess I've all the information I need.

This is an interface to the frogs CLI. It's not really designed to use its functions directly but to execute scripts from the command line. I guess in that case it's simpler to design the interface like the quarto package, which uses Sys.which() to get the path of the app and then generates and executes specific commands. For example:

foo <- function(a, b, ...) {
  args <- c("--arg-1", a "--arg-2", b, ...)
  system2(normalizePath(Sys.which("app")), args)
}

I don't have access to the server yet and I'm not responsible for the installation of python and other dependencies on the server though. I hope Sys.which() will work there too.

1 Like

For CLI apps distributed as Python packages, you can also use uv_run_tool(), which will automatically take care of installing the Python dependencies in an isolated Python environment.

Something like this:

reticulate::uv_run_tool("app", args)
2 Likes