Skip to content

Commit

Permalink
update to http api 0.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinSchobben committed Sep 17, 2024
1 parent defa2ca commit d47269b
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 163 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Imports:
stats,
testthat (>= 3.0.0),
utils,
withr
withr,
yaml
Suggests:
httptest2,
kableExtra,
Expand Down
25 changes: 25 additions & 0 deletions R/docker-yaml.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
get_docker_compose_path <- function() {
system.file("irods_demo/docker-compose.yml", package = "rirods")
}

get_docker_yaml <- function() {
docker_compose_file <- yaml::read_yaml(get_docker_compose_path(), handlers = list(
# make sure that sequences of size one are read as list
# (defaults to vector of length one)
seq = function(x) {
x <- as.list(x)
x
}
))
}

is_irods_service_in_yaml <- function(services, docker_compose_file) {
docker_compose_service_names <- names(docker_compose_file[["services"]])
irods_services_pattern <- paste0(services, collapse = "|")
grepl(irods_services_pattern, docker_compose_service_names)
}

extract_irods_services_names <- function(services) {
docker_compose_file <- get_docker_yaml()
names(docker_compose_file[["services"]])[is_irods_service_in_yaml(services, docker_compose_file)]
}
20 changes: 8 additions & 12 deletions R/irods-demo.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,15 @@ stop_irods_demo <- function(verbose = TRUE) {
#' @examples
#' is_irods_demo_running()
is_irods_demo_running <- function(...) {
# first check if Docker exist
# first check if Docker exists
if (!check_docker(FALSE)) {
return(FALSE)
}
# then check if images exist
# then check if images exists
if (!check_irods_images()) {
return(FALSE)
}
# check for client-icommand is not required (only needed for demo itself)
ref <- irods_containers_ref()
ref <- ref[ref != "irods-demo-irods-client-icommands-1"]
irods_containers_state <-
vapply(ref, is_irods_demo_running_, integer(1))

Expand Down Expand Up @@ -163,9 +161,9 @@ remove_docker_images <- function() {

start_irods <- function(verbose, recreate = TRUE) {
if (isTRUE(recreate)) {
cmd <- " ; docker compose up -d --force-recreate nginx-reverse-proxy irods-client-http-api irods-client-icommands"
cmd <- " ; docker compose up -d --force-recreate "
} else {
cmd <- " ; docker compose up -d nginx-reverse-proxy irods-client-http-api irods-client-icommands"
cmd <- " ; docker compose up -d "
}
system(
paste0("cd ", path_to_demo(), cmd),
Expand Down Expand Up @@ -219,6 +217,7 @@ is_http_server_running_correct <- function(user, pass, host, lpath) {
is_irods_server_running_correct <- function() {
system2(
system.file(package = "rirods", "shell_scripts", "dry-run-irods-icommands.sh"),
system.file("irods_demo", package = "rirods"),
stdout = FALSE,
stderr = FALSE
) == 0
Expand Down Expand Up @@ -262,12 +261,9 @@ check_docker <- function(verbose = TRUE) {
!(Sys.which("bash") == "" || Sys.which("docker") == "" || docker_version == "")
}

irods_containers_ref <- function() {
irods_demo_yml <- system.file("irods_demo", "docker-compose.yml", package = "rirods")
irods_demo_file <- readLines(irods_demo_yml)
irods_images_ref <- grep("^\\s{4}[[:graph:]]*?:$", irods_demo_file)
irods_images <- irods_demo_file[irods_images_ref]
paste0("irods-demo-", trimws(gsub( ":$", "", irods_images)), "-1")
irods_containers_ref <- function(services = c("nginx", "http-api", "icommands", "catalog")) {
docker_compose_service_names = extract_irods_services_names(services)
paste0("irods-demo-", docker_compose_service_names, "-1")
}

irods_images <- c(
Expand Down
2 changes: 1 addition & 1 deletion R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

.onLoad <- function(libname, pkgname) {
ns <- topenv()
ns$.irods_host <- "http://localhost:9001/irods-http-api/0.2.0"
ns$.irods_host <- "http://localhost:9001/irods-http-api/0.4.0"
}
2 changes: 1 addition & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ substitute(create_irods(x), list(x = rirods:::.irods_host))
```

```{r project, eval=is_irods_demo_running(), echo=FALSE}
eval(substitute(create_irods(x), list(x = rirods:::.irods_host)))
eval(substitute(create_irods(x), list(x = URLencode(rirods:::.irods_host))))
```

### Authentication
Expand Down
213 changes: 120 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

<!-- README.md is generated from README.Rmd. Please edit that file -->

# rirods <a href="https://dplyr.tidyverse.org"><img src="man/figures/logo.png" align="right" height="138" /></a>
Expand All @@ -15,27 +16,33 @@ The rirods package is an R client for iRODS.

You can install the latest CRAN version of rirods like so:

install.packages("rirods")
``` r
install.packages("rirods")
```

Or, the development version from GitHub, like so:

# install.packages("devtools")
devtools::install_github("irods/irods_client_library_rirods")
``` r
# install.packages("devtools")
devtools::install_github("irods/irods_client_library_rirods")
```

## Prerequisites

This package connects to the iRODS C++ HTTP API -
<https://github.com/irods/irods_client_http_api>.
https://github.com/irods/irods_client_http_api.

Launch a local demonstration iRODS service (including the HTTP API):

# load
library(rirods)
# setup a mock iRODS server (https://github.com/irods/irods_demo)
use_irods_demo("alice", "passWORD")
``` r
# load
library(rirods)
# setup a mock iRODS server (https://github.com/irods/irods_demo)
use_irods_demo("alice", "passWORD")
```

This will result in the demonstration HTTP API running at
<http://localhost:9001/irods-http-api/0.2.0>.
http://localhost:9001/irods-http-api/0.2.0.

These Docker containers are designed to easily stand up a
**DEMONSTRATION** of the iRODS server. It is intended for education and
Expand All @@ -57,44 +64,50 @@ In this example Alice is a user of iRODS and she can authenticate
herself with `iauth("alice")`. This prompts a dialog where you can enter
your password without hardcoding this information in your scripts.

# login as alice with password "passWORD"
iauth("alice") # or iauth("alice", "passWORD")
``` r
# login as alice with password "passWORD"
iauth("alice") # or iauth("alice", "passWORD")
```

### Save R objects

Suppose Alice would like to upload an R object from her current R
session to an iRODS collection. For this, use the `isaveRDS()` command:

# some data
foo <- data.frame(x = c(1, 8, 9), y = c("x", "y", "z"))
``` r
# some data
foo <- data.frame(x = c(1, 8, 9), y = c("x", "y", "z"))

# check where we are in the iRODS namespace
ipwd()
#> [1] "/tempZone/home/alice"
# check where we are in the iRODS namespace
ipwd()
#> [1] "/tempZone/home/alice"

# store data in iRODS
isaveRDS(foo, "foo.rds")
# store data in iRODS
isaveRDS(foo, "foo.rds")
```

### Metadata

To truly appreciate the strength of iRODS, we can add some metadata that
describes the data object “foo”:

# add some metadata
imeta(
"foo.rds",
operations =
data.frame(operation = "add", attribute = "foo", value = "bar", units = "baz")
)

# check if file is stored with associated metadata
ils(metadata = TRUE)
#>
#> ==========
#> iRODS Zone
#> ==========
#> logical_path attribute value units
#> /tempZone/home/alice/foo.rds foo bar baz
``` r
# add some metadata
imeta(
"foo.rds",
operations =
data.frame(operation = "add", attribute = "foo", value = "bar", units = "baz")
)

# check if file is stored with associated metadata
ils(metadata = TRUE)
#>
#> ==========
#> iRODS Zone
#> ==========
#> logical_path attribute value units
#> /tempZone/home/alice/foo.rds foo bar baz
```

For more on using metadata, check out `vignette("metadata")`.

Expand All @@ -103,91 +116,105 @@ For more on using metadata, check out `vignette("metadata")`.
If Alice wanted to copy the foo R object from an iRODS collection to her
current R session, she would use `ireadRDS()`:

# retrieve in native R format
ireadRDS("foo.rds")
#> x y
#> 1 1 x
#> 2 8 y
#> 3 9 z
``` r
# retrieve in native R format
ireadRDS("foo.rds")
#> x y
#> 1 1 x
#> 2 8 y
#> 3 9 z
```

### Other file formats

Possibly Alice does not want a native R object to be stored on iRODS but
a file type that can be accessed by other programs. For this, use the
`iput()` command:

library(readr)
``` r
library(readr)

# creates a csv file of foo
write_csv(foo, "foo.csv")
# creates a csv file of foo
write_csv(foo, "foo.csv")

# send file
iput("foo.csv", "foo.csv")
# send file
iput("foo.csv", "foo.csv")

# check whether it is stored
ils()
#>
#> ==========
#> iRODS Zone
#> ==========
#> logical_path
#> /tempZone/home/alice/foo.csv
#> /tempZone/home/alice/foo.rds
# check whether it is stored
ils()
#>
#> ==========
#> iRODS Zone
#> ==========
#> logical_path
#> /tempZone/home/alice/foo.csv
#> /tempZone/home/alice/foo.rds
```

Later on somebody else might want to download this file again and store
it locally:

# retrieve it again later
iget("foo.csv", "foo.csv")
read_csv("foo.csv")
#> Rows: 3 Columns: 2
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (1): y
#> dbl (1): x
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#> # A tibble: 3 × 2
#> x y
#> <dbl> <chr>
#> 1 1 x
#> 2 8 y
#> 3 9 z
``` r
# retrieve it again later
iget("foo.csv", "foo.csv")
read_csv("foo.csv")
#> Rows: 3 Columns: 2
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (1): y
#> dbl (1): x
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#> # A tibble: 3 × 2
#> x y
#> <dbl> <chr>
#> 1 1 x
#> 2 8 y
#> 3 9 z
```

### Query

By adding metadata you and others can more easily discover data in
future projects. Objects can be searched with General Queries and
`iquery()`:

# look for objects in the home collection with a wildcard `%`
iquery("SELECT COLL_NAME, DATA_NAME WHERE COLL_NAME LIKE '/tempZone/home/%'")
#> COLL_NAME DATA_NAME
#> 1 /tempZone/home/alice foo.csv
#> 2 /tempZone/home/alice foo.rds

# or for data objects with a name that starts with "foo"
iquery("SELECT COLL_NAME, DATA_NAME WHERE DATA_NAME LIKE 'foo%'")
#> COLL_NAME DATA_NAME
#> 1 /tempZone/home/alice foo.csv
#> 2 /tempZone/home/alice foo.rds
``` r
# look for objects in the home collection with a wildcard `%`
iquery("SELECT COLL_NAME, DATA_NAME WHERE COLL_NAME LIKE '/tempZone/home/%'")
#> COLL_NAME DATA_NAME
#> 1 /tempZone/home/alice foo.csv
#> 2 /tempZone/home/alice foo.rds
```

``` r
# or for data objects with a name that starts with "foo"
iquery("SELECT COLL_NAME, DATA_NAME WHERE DATA_NAME LIKE 'foo%'")
#> COLL_NAME DATA_NAME
#> 1 /tempZone/home/alice foo.csv
#> 2 /tempZone/home/alice foo.rds
```

For more on querying, check out `vignette("metadata")`.

### Cleanup

Finally, we can clean up Alice’s home collection:

# delete object
irm("foo.rds", force = TRUE)
irm("foo.csv", force = TRUE)

# check if objects are removed
ils()
#> This collection does not contain any objects or collections.

# close the server
stop_irods_demo()
# optionally remove the Docker images
# irods:::remove_docker_images()
``` r
# delete object
irm("foo.rds", force = TRUE)
irm("foo.csv", force = TRUE)

# check if objects are removed
ils()
#> This collection does not contain any objects or collections.
```

``` r
# close the server
stop_irods_demo()
# optionally remove the Docker images
# irods:::remove_docker_images()
```
Loading

0 comments on commit d47269b

Please sign in to comment.