Skip to content

Commit

Permalink
Add printing to remaining classes (#31)
Browse files Browse the repository at this point in the history
* Add printing to Instance

* Add get methods for settings and api to Instance

* Add printing to InstanceSettings

* Add printing to InstanceAPI

* Move repeated printing code to separate functions

* Add printing to Field

* Modify make_key_value_strings() to handle lists

* Add printing to Registry

Different output format to match Python

* Add printing to UserSettings

* Remove link fields from Registry print

Match Python output

* Add printint to Module

Adjust Registry printing

* Style and document print methods

* Remove titles from R6 method docs

These would cause issues if the docs are ever rendered. Content was
moved to @description.

* Render README

* Update CHANGELOG

* Update Instance printing to long format

* Fix lint

---------

Co-authored-by: Robrecht Cannoodt <[email protected]>
  • Loading branch information
lazappi and rcannood authored Oct 11, 2024
1 parent 11aedcb commit bca4137
Show file tree
Hide file tree
Showing 12 changed files with 460 additions and 58 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

* Add `to_string()` and `print()` methods to the `Record` class and (incomplete) `describe()` method to the `Artifact()` class (PR #22).

* Add `to_string()` and `print()` methods to remaining classes (PR #31)

## MAJOR CHANGES

* Refactored the internal class data structures for better modularity and extensibility (PR #8).
Expand Down
14 changes: 8 additions & 6 deletions R/Artifact.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ ArtifactRecord <- R6::R6Class( # nolint object_name_linter
"ArtifactRecord",
inherit = Record,
public = list(
#' Load the artifact into memory
#'
#' @description
#' This currently only supports AnnData artifacts.
#' Load the artifact into memory. This currently only supports AnnData
#' artifacts.
#'
#' @return The artifact
load = function() {
Expand All @@ -26,10 +25,9 @@ ArtifactRecord <- R6::R6Class( # nolint object_name_linter
cli_abort(paste0("Unsupported accessor: ", artifact_accessor))
}
},
#' Cache the artifact to the local filesystem
#'
#' @description
#' This currently only supports S3 storage.
#' Cache the artifact to the local filesystem. This currently only supports
#' S3 storage.
#'
#' @return The path to the cached artifact
cache = function() {
Expand All @@ -50,6 +48,10 @@ ArtifactRecord <- R6::R6Class( # nolint object_name_linter
cli_abort(paste0("Unsupported storage type: ", artifact_storage$type))
}
},
#' @description
#' Print a more detailed description of an `ArtifactRecord`
#'
#' @param style Logical, whether the output is styled using ANSI codes
describe = function(style = TRUE) {
provenance_fields <- c(
storage = "root",
Expand Down
33 changes: 33 additions & 0 deletions R/Field.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,39 @@ Field <- R6::R6Class( # nolint object_name_linter
private$.related_field_name <- related_field_name
private$.related_registry_name <- related_registry_name
private$.related_module_name <- related_module_name
},
#' @description
#' Print a `Field`
#'
#' @param style Logical, whether the output is styled using ANSI codes
print = function(style = TRUE) {
cli::cat_line(self$to_string(style))
},
#' @description
#' Create a string representation of a `Field`
#'
#' @param style Logical, whether the output is styled using ANSI codes
#'
#' @return A `cli::cli_ansi_string` if `style = TRUE` or a character vector
to_string = function(style = FALSE) {
field_strings <- make_key_value_strings(
self,
c(
"field_name",
"column_name",
"type",
"registry_name",
"module_name",
"through",
"is_link_table",
"relation_type",
"related_field_name",
"related_registry_name",
"related_module_name"
)
)

make_class_string("Field", field_strings, style = style)
}
),
private = list(
Expand Down
108 changes: 108 additions & 0 deletions R/Instance.R
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,114 @@ Instance <- R6::R6Class( # nolint object_name_linter
#' Get the names of the modules. Example: `c("core", "bionty")`.
get_module_names = function() {
names(private$.module_classes)
},
#' Get instance settings.
get_settings = function() {
private$.settings
},
#' Get instance API.
get_api = function() {
private$.api
},
#' @description
#' Print an `Instance`
#'
#' @param style Logical, whether the output is styled using ANSI codes
print = function(style = TRUE) {

registries <- self$get_module("core")$get_registries()

is_link_table <- purrr::map(registries, "is_link_table") |>
unlist()

standard_lines <- purrr::map_chr(
names(registries)[!is_link_table],
function(.registry) {
cli::col_blue(paste0(" $", registries[[.registry]]$class_name))
}
)

link_lines <- purrr::map_chr(
names(registries)[is_link_table],
function(.registry) {
cli::col_blue(paste0(" ", .registry))
}
)

lines <- c(
cli::style_bold(cli::col_green(private$.settings$name)),
cli::style_italic(cli::col_magenta(" Core registries")),
standard_lines,
cli::style_italic(cli::col_magenta(" Core link tables")),
link_lines
)

module_names <- self$get_module_names()
module_names <- module_names[module_names != "core"]

if (length(module_names) > 0) {
lines <- c(
lines,
cli::style_italic(cli::col_magenta(" Additional modules")),
cli::col_blue(paste0(" ", module_names))
)
}

if (isFALSE(style)) {
lines <- cli::ansi_strip(lines)
}

purrr::walk(lines, cli::cat_line)
},
#' @description
#' Create a string representation of an `Instance`
#'
#' @param style Logical, whether the output is styled using ANSI codes
#'
#' @return A `cli::cli_ansi_string` if `style = TRUE` or a character vector
to_string = function(style = FALSE) {
registries <- self$get_module("core")$get_registries()

is_link_table <- purrr::map(registries, "is_link_table") |>
unlist()

mapping <- list(
"CoreRegistries" = paste0(
"[",
paste(
paste0(
"$",
purrr::map_chr(registries[!is_link_table], "class_name")
),
collapse = ", "
),
"]"
),
"CoreLinkTables" = paste0(
"[",
paste(names(registries[is_link_table]), collapse = ", "),
"]"
)
)

module_names <- self$get_module_names()
module_names <- module_names[module_names != "core"]

if (length(module_names) > 0) {
mapping["AdditionalModules"] <- paste0(
"[",
paste(module_names, collapse = ", "),
"]"
)
}

key_value_strings <- make_key_value_strings(
mapping, quote_strings = FALSE
)

make_class_string(
private$.settings$name, key_value_strings, style = style
)
}
),
private = list(
Expand Down
23 changes: 23 additions & 0 deletions R/InstanceAPI.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ InstanceAPI <- R6::R6Class( # nolint object_name_linter
initialize = function(instance_settings) {
private$.instance_settings <- instance_settings
},
#' @description
#' Get the schema for the instance.
get_schema = function() {
# TODO: replace with laminr.api get_schema call
Expand All @@ -30,7 +31,9 @@ InstanceAPI <- R6::R6Class( # nolint object_name_linter

private$process_response(response, "get schema")
},
#' @description
#' Get a record from the instance.
#'
#' @importFrom jsonlite toJSON
get_record = function(module_name,
registry_name,
Expand Down Expand Up @@ -107,6 +110,26 @@ InstanceAPI <- R6::R6Class( # nolint object_name_linter
}

content
},
#' @description
#' Print an `API`
#'
#' @param style Logical, whether the output is styled using ANSI codes
print = function(style = TRUE) {
cli::cat_line(self$to_string(style))
},
#' @description
#' Create a string representation of an `API`
#'
#' @param style Logical, whether the output is styled using ANSI codes
#'
#' @return A `cli::cli_ansi_string` if `style = TRUE` or a character vector
to_string = function(style = FALSE) {
field_strings <- make_key_value_strings(
private$.instance_settings, c("api_url", "id", "schema_id")
)

make_class_string("API", field_strings, style = style)
}
)
)
18 changes: 18 additions & 0 deletions R/InstanceSettings.R
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ InstanceSettings <- R6::R6Class( # nolint object_name_linter
cli_abort("Unexpected key{?s}: {unexpected_keys}")
}
private$.settings <- settings
},
#' @description
#' Print an `InstanceSettings`
#'
#' @param style Logical, whether the output is styled using ANSI codes
print = function(style = TRUE) {
cli::cat_line(self$to_string(style))
},
#' @description
#' Create a string representation of an `InstanceSettings`
#'
#' @param style Logical, whether the output is styled using ANSI codes
#'
#' @return A `cli::cli_ansi_string` if `style = TRUE` or a character vector
to_string = function(style = FALSE) {
field_strings <- make_key_value_strings(private$.settings)

make_class_string("InstanceSettings", field_strings, style = style)
}
),
private = list(
Expand Down
77 changes: 77 additions & 0 deletions R/Module.R
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,94 @@ Module <- R6::R6Class( # nolint object_name_linter
) |>
set_names(names(module_schema))
},
#' @description
#' Get the registries in the module.
get_registries = function() {
private$.registry_classes
},
#' @description
#' Get a registry by name.
get_registry = function(registry_name) {
private$.registry_classes[[registry_name]]
},
#' @description
#' Get the names of the registries in the module. E.g. `c("User", "Artifact")`.
get_registry_names = function() {
names(private$.registry_classes)
},
#' @description
#' Print a `Module`
#'
#' @param style Logical, whether the output is styled using ANSI codes
print = function(style = TRUE) {
registries <- self$get_registries()

is_link_table <- purrr::map(registries, "is_link_table") |>
unlist()

standard_lines <- purrr::map_chr(
names(registries)[!is_link_table],
function(.registry) {
cli::col_blue(paste0(" $", registries[[.registry]]$class_name))
}
)

link_lines <- purrr::map_chr(
names(registries)[is_link_table],
function(.registry) {
cli::col_blue(paste0(" ", .registry))
}
)

lines <- c(
cli::style_bold(cli::col_green(private$.module_name)),
cli::style_italic(cli::col_magenta(" Registries")),
standard_lines,
cli::style_italic(cli::col_magenta(" Link tables")),
link_lines
)

if (isFALSE(style)) {
lines <- cli::ansi_strip(lines)
}

purrr::walk(lines, cli::cat_line)
},
#' @description
#' Create a string representation of a `Module`
#'
#' @param style Logical, whether the output is styled using ANSI codes
#'
#' @return A `cli::cli_ansi_string` if `style = TRUE` or a character vector
to_string = function(style = FALSE) {
registries <- self$get_registries()

is_link_table <- purrr::map(registries, "is_link_table") |>
unlist()

registry_strings <- make_key_value_strings(
list(
"Registries" = paste0(
"[",
paste(
paste0(
"$",
purrr::map_chr(registries[!is_link_table], "class_name")
),
collapse = ", "
),
"]"
),
"LinkTables" = paste0(
"[",
paste(names(registries[is_link_table]), collapse = ", "),
"]"
)
),
quote_strings = FALSE
)

make_class_string(private$.module_name, registry_strings, style = style)
}
),
private = list(
Expand Down
Loading

0 comments on commit bca4137

Please sign in to comment.