Error while evaluating resource on client side

Hello,

we try to work around the problem discussed in How to pass models between data scientists and nodes.

We saved our model as model.RData and model.rds files, then we assigned them as resources in our project as R data file - Opal and RDS data file -Opal (path set as : /projects/my_project/model.RData).

When we assign them in a R session:

datashield.assign.resource(connections, symbol="D", resource="my_project.RESOURCE")

and when we try to access them as

datashield.assign.expr(connections, "T", expr=quote(as.resource.object(D)))

or

resource[[1]]$getValue()

we encounter an error:

Command as.resource.object(D) failed on server: Error while evaluating is.null(base::assign("T", value={resourcer::as.resource.object(D)})) -> Error in load(path,envir = private$.env): empty (zero-byte) input file

These objects are saved exactly along the path set in the resource.

Any ideas?

Thank you in advance

Hi,

Most likely because the file retrieval from Opal failed (thus the empty file).

How have you created this resource: using the web interface or an R script?
Can you verify that the credentials of the resource are correct? It must be a personal access token.

Regards
Yannick

I created the resource using both web interface and R script, which ended up with the same effect.

I login to the opal using:

o <- opal.login("login", "password", token="TOKEN", url="URL")

TOKEN is the same as the one set on the resource.

I had the same error when I set the resource as local object, which has no credentials required.

When you test with R, in opal.login(), do not use both username/password and token, because token will be ignored. Use one authentication method or the other.

And what about the local file resource? What path shoud the resource contain? I tried to access the resource via:

DSI::datashield.assign.resource(connections, "RESOURCE", "PROJ.RES")
DSI::datashield.assign.expr(connections, "DF", expr = quote(as.resource.data.frame(RESOURCE)))

I always get test.csv does not exist. It’s not clear to me what path should the resource contain. I have tried:

  • /projects/my_proj/test.csv
  • /srv/fs/projects/my_proj/test.csv
  • /test.csv

Any Idea?

It is hard to tell, I do not know your setup.

  • The local file resource has a path in the R server host, readable by the R server application.
  • A path in Opal is only valid in the Opal context (i.e. accessed by Opal).

How do you verify your resource is accessible using R?

A small trick to know what your R server host has access to is doing system calls as the R session through opalr.

library(opalr)
o <- opal.login(url = "https://opal.XXXX.org", username = "user", password = "pass")
opal.execute(o, script = 'system("ls -lh /var/lib/rserver/work/projects/Athlete", intern = TRUE)')

That way you can be sure the local path were the files of interest are located and properly format the resource URL, as well as veryfying that the R session can actually see the path.

On the proposed code I can see the file xxx.Rdata; so I would create a resource as:

opal.resource_create(o, 'project', 'resource', 'file:///var/lib/rserver/work/projects/Athlete/xxx.Rdata',
                     format = 'Rdata')

I hope this can help. Xavier.

1 Like

Hi,

Were you able to make it work?

As an example, the following script can help:

# Resource data
library(opalr)
o <- opal.login(username = "administrator", password = "password", url = "https://opal-demo.obiba.org")
# prepare project
if (!opal.project_exists(o, "test"))
  opal.project_create(o, "test")
# prepare data and upload in project's folder
saveRDS(mtcars, "mtcars.rds")
opal.file_upload(o, "mtcars.rds", "/projects/test")
unlink("mtcars.rds")
# make a personal access token
token <- opal.token_r_create(o, "mtcars", projects = "test")
# make the resource
opal.resource_create(o, "test", "mtcars", 
                     url = "opal+https://opal-demo.obiba.org/ws/files/projects/test/mtcars.rds",
                     format = "data.frame",
                     secret = token)
# verify
opal.resource_get(o, "test", "mtcars")
# set permission
opal.resource_perm_add(o, "test", "mtcars", "dsuser", permission = "view")
opal.logout(o)

Then use the resource in DataSHIELD:

# DataSHIELD
library(DSOpal)
library(dsBaseClient)
builder <- DSI::newDSLoginBuilder()
builder$append(server = "demo", user = "dsuser", password = "password", url = "https://opal-demo.obiba.org")
logindata <- builder$build()
conns <- datashield.login(logindata)
datashield.assign.resource(conns, "client", "test.mtcars")
datashield.assign.expr(conns, "df", expr = quote(as.resource.data.frame(client, strict = TRUE)))
ds.colnames("df")
datashield.logout(conns)

Regards
Yannick