Skip to content

Commit

Permalink
Merge pull request #118 from NovoNordisk-OpenSource/feat/run-python-r…
Browse files Browse the repository at this point in the history
…eview

feat: integrate python logging directly in functions
  • Loading branch information
akselthomsen authored Nov 11, 2024
2 parents 2051376 + 0aef79c commit 80ef2a1
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 106 deletions.
54 changes: 44 additions & 10 deletions R/session.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#' Get session info
#'
#' Retrieve session info and add quarto info if not already there
#' Argument to also add python version and package info
#'
#' @noRd

session_info <- function(approved_folder_pkgs, approved_url_pkgs) {
session_info <- function(approved_folder_pkgs = NULL, approved_url_pkgs = NULL, python_packages = NULL) {
info <- sessioninfo::session_info()

if (!is.null(approved_folder_pkgs) |
Expand All @@ -30,7 +31,7 @@ session_info <- function(approved_folder_pkgs, approved_url_pkgs) {
info$options <- info$options[!names(info$options) %in% "rl_word_breaks"]
class(info$options) <- c("options_info", class(info$options))

# TODO: Extend to also cover external and python below in methods.
# TODO: Extend to also cover external.
info[!names(info) %in% c("platform", "packages", "environment", "options")] <- NULL

if (is.null(info$platform$quarto)) {
Expand All @@ -44,6 +45,19 @@ session_info <- function(approved_folder_pkgs, approved_url_pkgs) {
}
}

if (!is.null(python_packages)) {

# TODO: Get the same information as for R packages (not only name and version)
# TODO: Only show used, and not all installed, packages if possible

info$python_packages <- python_packages
class(info$python_packages) <- c("packages_info", class(info$python_packages))

quarto_python_path <- Sys.getenv("QUARTO_PYTHON")
quarto_python_version <- gsub(".*/([0-9]+\\.[0-9]+\\.[0-9]+)/.*", "\\1", quarto_python_path)
info$platform$python <- quarto_python_version
}

class(info) <- c("whirl_session_info", class(info))
for (i in seq_along(info)) {
class(info[[i]]) <- c(paste0("whirl_", class(info[[i]])[[1]]), class(info[[i]]))
Expand All @@ -52,6 +66,21 @@ session_info <- function(approved_folder_pkgs, approved_url_pkgs) {
return(info)
}

#' Get Python package info from json file
#'
#' @noRd

python_package_info <- function(json) {

json |>
jsonlite::fromJSON() |>
tibble::enframe(name = "Package") |>
tidyr::unnest_wider(col = value) |>
dplyr::rename(
Version = version,
Path = installation_path
)
}

#' @noRd

Expand Down Expand Up @@ -81,13 +110,18 @@ knit_print.whirl_platform_info <- function(x, ...) {
#' @noRd

knit_print.whirl_packages_info <- function(x, ...) {
data.frame(
Package = x$package,
Version = x$loadedversion,
`Date (UTC)` = x$date,
Source = x$source,
check.names = FALSE
) |>

if (!is.null(x$package)){
x <- data.frame(
Package = x$package,
Version = x$loadedversion,
`Date (UTC)` = x$date,
Source = x$source,
check.names = FALSE
)
}

x |>
knitr::kable() |>
kableExtra::kable_styling(
bootstrap_options = "striped",
Expand All @@ -97,7 +131,7 @@ knit_print.whirl_packages_info <- function(x, ...) {
}

#' @noRd
#'

knit_print.whirl_approved_pkgs <- function(x, ...) {
hold <- x |>
data.frame(
Expand Down
33 changes: 25 additions & 8 deletions R/status.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,27 @@ get_status <- function(md) {

x <- x[[1]]

add_python <- x |>
stringr::str_detect("\\{.python .cell-code") |>
any()

# Errors

errors <- x |>
stringr::str_subset(pattern = "^ *\\{\\.cell-output \\.cell-output-error\\}") |>
stringr::str_remove_all("\\{[^\\}]*\\}") |>
stringr::str_squish()

python_errors <- x |>
stringr::str_subset(pattern = "(?i).*Error.*") |>
stringr::str_remove_all("\\{[^\\}]*\\}") |>
stringr::str_squish()

errors <- c(errors, python_errors)


if (add_python) {
python_errors <- x |>
stringr::str_subset(pattern = "^ *\\{\\.cell-output") |>
stringr::str_remove_all("\\{[^\\}]*\\}") |>
stringr::str_squish() |>
stringr::str_subset("Error:")

errors <- c(errors, python_errors)
}

# Warnings

warnings <- x |>
Expand All @@ -33,6 +40,16 @@ get_status <- function(md) {
stringr::str_squish() |>
stringr::str_subset(pattern = "^(W|w)arning")

if (add_python) {
python_warnings <- x |>
stringr::str_subset(pattern = "^ *\\{\\.cell-output") |>
stringr::str_remove_all("\\{[^\\}]*\\}") |>
stringr::str_squish() |>
stringr::str_subset("Warning:")

warnings <- c(warnings, python_warnings)
}

# Status

if (length(errors)) {
Expand Down
73 changes: 41 additions & 32 deletions inst/documents/dummy.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ params:
tmpdir: "."
---

```{r setup, include=FALSE}
```{r setup}
#| label: Setup
#| include: false
knitr::opts_chunk$set(
error = TRUE,
warning = TRUE,
Expand All @@ -19,48 +22,56 @@ knitr::opts_chunk$set(
.libPaths(c(character(), params$with_library_paths))
```

```{r, echo=FALSE, eval=(grepl("\\.R$", params$script))}
```{r}
#| label: Log R
#| eval: !expr grepl("\\.R$", params$script)
#| echo: false
knitr::spin_child(params$script)
```

```{r, child = params$script, eval=(grepl("\\.qmd$", params$script))}
```{r}
#| label: Log Quarto
#| child: !expr params$script
#| eval: !expr grepl("\\.qmd$", params$script)
#| include: !expr grepl("\\.qmd$", params$script)
```

```{r, child = params$script, eval=(grepl("\\.Rmd$", params$script))}
```{r}
#| label: Log Rmarkdown
#| child: !expr params$script
#| eval: !expr grepl("\\.Rmd$", params$script)
#| include: !expr grepl("\\.Rmd$", params$script)
```

```{python, file=params$script, eval=(grepl("\\.py$", params$script))}
```{python}
#| label: Log Python
#| file: !expr params$script
#| eval: !expr grepl("\\.py$", params$script)
#| include: !expr grepl("\\.py$", params$script)
```

```{python, eval=(grepl("\\.py$", params$script)), echo=FALSE}
import json
import sys
import subprocess
temp_dir = r.params['tmpdir']
# Get a list of installed packages using pip list
installed_packages = subprocess.check_output([sys.executable, '-m', 'pip', 'list', '-v']).decode('utf-8').strip().split('\n')[2:]
installed_packages = {package.split()[0]: [package.split()[1], package.split()[2]] for package in installed_packages}
imported_modules = {}
for module_name, module in sys.modules.items():
if not (module_name.startswith('_') or module_name.startswith('.') or '.' in module_name):
if module_name in installed_packages:
imported_modules[module_name] = {
"version": installed_packages[module_name][0],
"installation_path": installed_packages[module_name][1]
}
with open(f'{temp_dir}/python_imports.json', 'w') as json_file:
json.dump(imported_modules, json_file)
```{python}
#| label: Python modules
#| file: !expr file.path(params$tmpdir, "python_modules.py")
#| eval: !expr grepl("\\.py$", params$script)
#| echo: false
```

```{r}
#| label: Session info
#| include: false
python_packages <- NULL
if (file.exists(file.path(params$tmpdir, "python_imports.json"))){
python_packages <- whirl:::python_package_info(file.path(params$tmpdir, "python_imports.json"))
}
```{r sessioninfo, include=FALSE}
saveRDS(
object = whirl:::session_info(params$check_approved_folder_pkgs, params$check_approved_url_pkgs),
object = whirl:::session_info(
approved_folder_pkgs = params$check_approved_folder_pkgs,
approved_url_pkgs = params$check_approved_url_pkgs,
python_packages = python_packages
),
file = file.path(params$tmpdir, "session_info.rds")
)
Expand All @@ -70,6 +81,4 @@ if (is.character(params$renv) && params$renv == "yes" | is.logical(params$renv)
file = file.path(params$tmpdir, "renv_status.rds")
)
}
```

Loading

0 comments on commit 80ef2a1

Please sign in to comment.