R/setup.R

Defines functions ensure_codecarbon_available carbon_tracker_ready setup_carbon_tracker

Documented in carbon_tracker_ready setup_carbon_tracker

#' Install codecarbon into a dedicated conda environment
#'
#' Installs Miniconda if it isn't already present, then creates the
#' "r-codecarbon" conda environment and installs codecarbon into it. Run this
#' once per machine before using [carbon_tracker()] or
#' [with_emissions_tracked()]. Nothing is installed without confirmation, and
#' the function refuses to run outside an interactive session.
#'
#' Installs codecarbon `>= 2.2.2` -- a floor, not an exact pin. That's the
#' oldest version this package has actually been validated against (see
#' `comparison/coverage_matrix.md` and `NEWS.md` for exactly which versions
#' were validated, and where); newer codecarbon releases are expected and
#' welcome, since they bring updated carbon-intensity data along with
#' whatever bug fixes landed upstream. codecarbon's behavior has changed
#' between versions before (see [carbon_tracker()]'s docs on tracker
#' restart), so if something about CodeCarbonR's output looks different
#' after a codecarbon upgrade, that's the first thing to check. Keep the
#' floor here in sync with DESCRIPTION's `SystemRequirements` field if it
#' changes.
#'
#' @param force Reinstall codecarbon even if it's already available.
#' @return Invisibly, `TRUE` if codecarbon is ready to use after the call,
#'   `FALSE` if setup was cancelled.
#' @examples
#' \dontrun{
#' # Installs software and prompts for confirmation, so this never runs
#' # under R CMD check (or any other non-interactive session) -- call it
#' # once, by hand, from an interactive R console.
#' setup_carbon_tracker()
#' }
#' @export
setup_carbon_tracker <- function(force = FALSE) {
  if (!force && carbon_tracker_ready()) {
    message("codecarbon is already installed.")
    return(invisible(TRUE))
  }

  if (!interactive()) {
    stop(
      "setup_carbon_tracker() must be run interactively so you can confirm ",
      "the install. Call it from the R console.",
      call. = FALSE
    )
  }

  miniconda_needed <- !dir.exists(reticulate::miniconda_path())
  message(
    "This will set up a Python environment for CodeCarbonR:\n",
    if (miniconda_needed) {
      sprintf("  - install Miniconda to %s\n", reticulate::miniconda_path())
    },
    "  - create a conda environment named \"r-codecarbon\"\n",
    "  - install the codecarbon Python package into it"
  )

  if (utils::menu(c("Yes", "No"), title = "Proceed?") != 1) {
    message("Setup cancelled.")
    return(invisible(FALSE))
  }

  if (miniconda_needed) {
    reticulate::install_miniconda()
  }
  reticulate::py_install("codecarbon>=2.2.2", envname = "r-codecarbon", method = "conda")

  if (!carbon_tracker_ready()) {
    stop("codecarbon did not install correctly. Run setup_carbon_tracker() again.", call. = FALSE)
  }

  message("codecarbon is installed and ready to use.")
  invisible(TRUE)
}

#' Check whether codecarbon is installed and importable
#'
#' @return `TRUE` if codecarbon can be imported, `FALSE` otherwise (including
#'   when no Python interpreter can be found at all).
#' @examples
#' \donttest{
#' # Not \dontrun{} -- this genuinely works, it's just slow: on a machine
#' # with no Python configured (e.g. a fresh CRAN check environment),
#' # reticulate's interpreter discovery alone can take >10s before this
#' # returns FALSE. \donttest{} keeps it out of the default check timing
#' # while still letting CRAN's extended checks and interactive users
#' # verify it actually runs.
#' carbon_tracker_ready()
#' }
#' @export
carbon_tracker_ready <- function() {
  tryCatch(reticulate::py_module_available("codecarbon"), error = function(e) FALSE)
}

ensure_codecarbon_available <- function() {
  if (carbon_tracker_ready()) {
    return(invisible(TRUE))
  }
  stop("codecarbon is not installed. Run setup_carbon_tracker() once to install it.", call. = FALSE)
}

Try the CodeCarbonR package in your browser

Any scripts or data that you put into this service are public.

CodeCarbonR documentation built on Sept. 21, 2026, 5:08 p.m.