# ==============================================================================
# Functions for constructing any arbitrary CyREST API or Commands API method via
# standard GET, PUT, POST and DELETE protocols. These functions handle marshalling
# and unmarshalling of urls, parameters and returns so that higher-level functions
# can work with R-friendly arguments and returns.
#
# I. CyREST API functions
# II. Commands API functions
# III. Internal functions
# IV. Jupyter-bridge
# V. Sandbox
#
# Note: This is where the bulk of the dependencies for other packages are used,
# e.g., utils, httr, RJSONIO, etc. Follow the use of @importFrom where prudent.
#
# ==============================================================================
# I. CyREST API functions
# ------------------------------------------------------------------------------
#' Open Swagger docs for CyREST API
#'
#' @description Opens swagger docs in default browser for a live
#' instance of CyREST operations.
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return Web page in browser
#' @export
#' @examples
#' \donttest{
#' cyrestAPI()
#' }
#' @importFrom utils browseURL
cyrestAPI<-function(base.url=.defaultBaseUrl){
if(!findRemoteCytoscape(base.url)){
browseURL(paste(base.url,'/swaggerUI/swagger-ui/index.html?url=',base.url,'/swagger.json#/',sep=""))
} else {
doRequestRemote("webbrowser", paste(base.url, '/swaggerUI/swagger-ui/index.html?url=',base.url,'/swagger.json#/',sep=""))
}
}
# ------------------------------------------------------------------------------
#' @title CyREST DELETE
#'
#' @description Constructs the query, makes DELETE call and processes the result.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' @param operation A string to be converted to the REST query namespace
#' @param parameters A named list of values to be converted to REST query parameters
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return CyREST result content
#' @examples \donttest{
#' cyrestDELETE('session')
#' }
#' @importFrom RJSONIO fromJSON isValidJSON
#' @importFrom httr DELETE
#' @importFrom utils URLencode
#' @export
cyrestDELETE <- function(operation=NULL, parameters=NULL, base.url=.defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
if(!findRemoteCytoscape(base.url)){
q.url <- paste(base.url, operation, sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
tryCatch(
res <- DELETE(url=URLencode(q.url)),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char))
} else {
return(res.char)
}
invisible(res)
}
} else {
q.url <- paste(base.url, .pathURLencode(operation), sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
res <- doRequestRemote("DELETE", URLencode(q.url))
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char))
} else {
return(res.char)
}
} else{
invisible(res)
}
}
}
# ------------------------------------------------------------------------------
#' @title CyREST GET
#'
#' @description Constructs the query, makes GET call and processes the result.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' @param operation A string to be converted to the REST query namespace
#' @param parameters A named list of values to be converted to REST query parameters
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return CyREST result content
#' @examples \donttest{
#' cyrestGET('version')
#' }
#' @importFrom RJSONIO fromJSON isValidJSON
#' @importFrom httr GET
#' @importFrom utils URLencode
#' @export
cyrestGET <- function(operation=NULL, parameters=NULL, base.url=.defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
if(!findRemoteCytoscape(base.url)){
q.url <- paste(base.url, operation, sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
tryCatch(
res <- GET(url=URLencode(q.url)),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char))
} else {
return(res.char)
}
} else{
invisible(res)
}
} else {
if(!is.null(operation)){
q.url <- paste(base.url, .pathURLencode(operation), sep="/")
} else {
q.url <- paste(base.url)
}
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
res <- doRequestRemote("GET", URLencode(q.url))
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(RJSONIO::fromJSON(res.char)$text))
} else {
return(res.char)
}
} else{
invisible(res)
}
}
}
# ------------------------------------------------------------------------------
#' @title CyREST POST
#'
#' @description Constructs the query and body, makes POST call and processes the result.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' @param operation A string to be converted to the REST query namespace
#' @param parameters A named list of values to be converted to REST query parameters
#' @param body A named list of values to be converted to JSON
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return CyREST result content
#' @examples \donttest{
#' cyrestPOST('networks/51/views')
#' }
#' @importFrom RJSONIO fromJSON toJSON isValidJSON
#' @importFrom httr POST content_type_json
#' @importFrom utils URLencode
#' @export
cyrestPOST <- function(operation, parameters=NULL, body=NULL, base.url=.defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
if(!findRemoteCytoscape(base.url)){
q.url <- paste(base.url, operation, sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
q.body <- toJSON(body)
tryCatch(
res <- POST(url=URLencode(q.url), body=q.body, encode="json", content_type_json()),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char))
} else {
return(res.char)
}
invisible(res)
}
} else {
q.url <- paste(base.url, .pathURLencode(operation), sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
q.body <- body
res <- doRequestRemote("POST", URLencode(q.url), q.body, headers=list("Content-Type" = "application/json"))
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char))
} else {
return(res.char)
}
} else{
invisible(res)
}
}
}
# ------------------------------------------------------------------------------
#' @title CyREST PUT
#'
#' @description Constructs the query and body, makes PUT call and processes the result.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' @param operation A string to be converted to the REST query namespace
#' @param parameters A named list of values to be converted to REST query parameters
#' @param body A named list of values to be converted to JSON
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return CyREST result content
#' @examples \donttest{
#' cyrestPUT()
#' }
#' @importFrom RJSONIO fromJSON isValidJSON toJSON
#' @importFrom httr PUT content_type_json
#' @importFrom utils URLencode
#' @export
cyrestPUT <- function(operation, parameters=NULL, body=NULL, base.url=.defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
if(!findRemoteCytoscape(base.url)){
q.url <- paste(base.url, operation, sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
q.body <- toJSON(body)
tryCatch(
res <- PUT(url=URLencode(q.url), body=q.body, encode="json", content_type_json()),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char))
} else {
return(res.char)
}
invisible(res)
}
} else {
q.url <- paste(base.url, .pathURLencode(operation), sep="/")
if(!is.null(parameters)){
q.params <- .prepGetQueryArgs(parameters)
q.url <- paste(q.url, q.params, sep="?")
}
q.body <- body
res <- doRequestRemote("PUT", URLencode(q.url), q.body, headers=list("Content-Type" = "application/json"))
if(length(res$content)>0){
res.char <- rawToChar(res$content)
if (RJSONIO::isValidJSON(res.char, asText = TRUE)){
return(RJSONIO::fromJSON(res.char)$text)
} else {
return(res.char)
}
} else{
invisible(res)
}
}
}
# ==============================================================================
# II. Commands API functions
# ------------------------------------------------------------------------------
#' Open Swagger docs for CyREST Commands API
#'
#' @description Opens swagger docs in default browser for a live
#' instance of Commands available via CyREST.
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return Web page in browser
#' @export
#' @examples
#' \donttest{
#' commandsAPI()
#' }
#' @importFrom utils browseURL
commandsAPI<-function(base.url=.defaultBaseUrl){
browseURL(paste(base.url,'/swaggerUI/swagger-ui/index.html?url=',base.url,'/commands/swagger.json#/',sep=""))
}
# ------------------------------------------------------------------------------
#' @title Commands GET
#'
#' @description Using the same syntax as Cytoscape's Command Line Dialog,
#' this function converts a command string into a CyREST query URL, executes a GET
#' request, and parses the result content into an R list object.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' Extremely long commands may result in an immediate "URI Too Long" failure because
#' `commandsRun()` uses HTTP GET to call the CyREST API, and HTTP GET has known limitations.
#' You can use `commandsPost()` instead, though the return value will be different.
#' `commandsPost()` uses HTTP POST, which has no limitations.
#' @param cmd.string (char) command
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return A \code{list}, \code{status} or None.
#' @examples
#' \donttest{
#' commandsGET('layout get preferred network=current')
#' commandsGET('network list properties network=current')
#' commandsGET('layout force-directed defaultNodeMass=1')
#' }
#' @importFrom XML htmlParse xmlValue xpathSApply
#' @importFrom httr GET
#' @export
commandsGET<-function(cmd.string, base.url = .defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
if(!findRemoteCytoscape(base.url)){
q.url <- .command2getQuery(cmd.string,base.url)
tryCatch(
res <- GET(q.url),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
res.html = htmlParse(rawToChar(res$content), asText=TRUE)
res.elem = xpathSApply(res.html, "//p", xmlValue)
if(startsWith(res.elem[1],"[")){
res.elem[1] = gsub("\\[|\\]|\"","",res.elem[1])
res.elem2 = unlist(strsplit(res.elem[1],"\n"))[1]
res.list = unlist(strsplit(res.elem2,","))
}else {
res.list = unlist(strsplit(res.elem[1],"\n\\s*"))
res.list = res.list[!(res.list=="Finished")]
}
if(length(res.list)>0){
res.list
} else {
invisible(res.list)
}
} else {
q.url <- .command2getQuery(cmd.string, base.url)
res <- doRequestRemote("GET", URLencode(q.url), headers=list("Accept" = "text/plain"))
res.html = htmlParse(rawToChar(res$content), asText=TRUE)
res.elem = xpathSApply(res.html, "//p", xmlValue)
if(startsWith(res.elem[1],"[")){
res.elem[1] = gsub("\\[|\\]|\"","",res.elem[1])
res.elem2 = unlist(strsplit(res.elem[1],"\n"))[1]
res.list = unlist(strsplit(res.elem2,","))
}else {
res.list = unlist(strsplit(res.elem[1],"\n\\s*"))
res.list = res.list[!(res.list=="Finished")]
}
if(length(res.list)>0){
unlist(strsplit(RJSONIO::fromJSON(res.list)$text,"\n"))
} else {
invisible(res.list)
}
}
}
# ------------------------------------------------------------------------------
#' @title Commands Help
#'
#' @description Using the same syntax as Cytoscape's Command Line Dialog,
#' this function returns a list of available commands or args.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' @details Works with or without 'help' command prefix. Note that if you ask about a command that doesn't
#' have any arguments, this function will run the command!
#' @param cmd.string (char) command
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return List of available commands or args
#' @examples
#' \donttest{
#' commandsHelp()
#' commandsHelp('node')
#' commandsHelp('node get attribute')
#' }
#' @importFrom XML htmlParse xmlValue xpathSApply
#' @importFrom httr GET
#' @importFrom utils head tail
#' @export
commandsHelp<-function(cmd.string='help', base.url = .defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
s=sub('help *','',cmd.string)
if(!findRemoteCytoscape(base.url)){
q.url <- .command2getQuery(s,base.url)
tryCatch(
res <- GET(q.url),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
res.html = htmlParse(rawToChar(res$content), asText=TRUE)
res.elem = xpathSApply(res.html, "//p", xmlValue)
res.list = res.elem
if (length(res.elem)==1){
res.list = unlist(strsplit(res.elem[1],"\n\\s*"))
}
print(head(res.list,1))
vapply(tail(res.list,-1), trimws, character(1), USE.NAMES = FALSE)
} else {
q.url <- .command2getQuery(s, base.url)
res <- doRequestRemote("GET", URLencode(q.url), headers=list("Accept" = "text/plain"))
res.html = htmlParse(rawToChar(res$content), asText=TRUE)
res.elem = xpathSApply(res.html, "//p", xmlValue)
res.elem = (RJSONIO::fromJSON(res.elem))$text
res.list = res.elem
if (length(res.elem)==1){
res.list = unlist(strsplit(res.elem[1],"\n\\s*"))
}
vapply(tail(res.list,-1), trimws, character(1), USE.NAMES = FALSE)
}
}
# ------------------------------------------------------------------------------
#' @title Commands POST
#'
#' @description Using the same syntax as Cytoscape's Command Line Dialog,
#' this function converts a command string into a CyREST query URL, executes a
#' POST request, and parses the result content into an R list object.
#' The function check whether actual call is local or remote first. If remote,
#' requests will go through Jupyter-Bridge.
#' @param cmd.string (char) command
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return A \code{list}, \code{named list}, \code{status} or None.
#' @examples
#' \donttest{
#' commandsPOST('layout get preferred')
#' commandsPOST('network list properties')
#' commandsPOST('layout force-directed defaultNodeMass=1')
#' }
#' @importFrom RJSONIO fromJSON
#' @importFrom httr POST content_type_json
#' @export
commandsPOST<-function(cmd.string, base.url = .defaultBaseUrl){
requester <- NULL
doInitializeSandbox(requester, base.url=base.url)
if(!findRemoteCytoscape(base.url)){
post.url = .command2postQueryUrl(cmd.string,base.url)
post.body = .command2postQueryBody(cmd.string)
tryCatch(
res <- POST(url=post.url, body=post.body, encode="json", content_type_json()),
error=function(c) .cyError(c, res),
warnings=function(c) .cyWarnings(c, res),
finally=.cyFinally(res)
)
if(length(res$content)>0){
res.data = RJSONIO::fromJSON(rawToChar(res$content))$data
if(length(res.data)>0){
return(res.data)
} else{
invisible(res.data)
}
}else {
invisible(res)
}
} else {
post.url = .command2postQueryUrl(cmd.string, base.url)
post.body = .command2postQueryBody(cmd.string)
post.body = RJSONIO::fromJSON(post.body)
res <- doRequestRemote("POST", post.url, post.body, headers=list("Content-Type" = "application/json", "Accept" = "application/json"))
if(length(res$content)>0){
res.data = RJSONIO::fromJSON(RJSONIO::fromJSON(rawToChar(res$content))$text)$data
if(length(res.data)>0){
return(res.data)
} else{
invisible(res.data)
}
}else {
invisible(res)
}
}
}
# ------------------------------------------------------------------------------
#' @title Run a Command
#'
#' @description Using the same syntax as Cytoscape's Command Line Dialog,
#' this function converts a command string into a CyREST query URL, executes a GET
#' request, and parses the result content into an R list object. Same as commandsGET.
#' Extremely long commands may result in an immediate "URI Too Long" failure because
#' `commandsRun()` uses HTTP GET to call the CyREST API, and HTTP GET has known limitations.
#' You can use `commandsPost()` instead, though the return value will be different.
#' `commandsPost()` uses HTTP POST, which has no limitations.
#' @param cmd.string (char) command
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return A \code{list}, \code{status} or None.
#' @examples
#' \donttest{
#' commandsRun('layout get preferred')
#' commandsRun('network list properties')
#' commandsRun('layout force-directed defaultNodeMass=1')
#' }
#' @export
commandsRun<-function(cmd.string, base.url = .defaultBaseUrl){
commandsGET(cmd.string,base.url)
}
# ------------------------------------------------------------------------------
#' @title Command Echo
#'
#' @description The echo command will display the value of the variable specified
#' by the variableName argument, or all variables if variableName is not provided.
#' @param variable.name (optional) The name of the variable to display. Default is
#' to display all variable values using "*".
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return Value of variable
#' @examples \donttest{
#' commandEcho()
#' }
#' @export
commandEcho <- function(variable.name="*", base.url = .defaultBaseUrl){
commandsPOST(paste0('command echo variableName="',variable.name,'"'),
base.url = base.url)
}
# ------------------------------------------------------------------------------
#' @title Command Open Dialog
#'
#' @description The command line dialog provides a field to enter commands and
#' view results. It also provides the help command to display namespaces,
#' commands, and arguments
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples \donttest{
#' commandOpenDialog()
#' }
#' @export
commandOpenDialog <- function(base.url = .defaultBaseUrl){
commandsPOST('command open dialog',
base.url = base.url)
}
# ------------------------------------------------------------------------------
#' @title Command Pause
#'
#' @description The pause command displays a dialog with the text provided in the
#' message argument and waits for the user to click OK.
#' @param message (optional) Text to display in pause dialog
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples \donttest{
#' commandPause('Please click OK to continue.')
#' }
#' @export
commandPause <- function(message="", base.url = .defaultBaseUrl){
commandsPOST(paste0('command pause message="',message,'"'),
base.url = base.url)
}
# ------------------------------------------------------------------------------
#' @title Command Quit
#'
#' @description This command causes Cytoscape to exit. It is typically used at
#' the end of a script file
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples \donttest{
#' commandQuit()
#' }
#' @export
commandQuit <- function(base.url = .defaultBaseUrl){
commandsPOST('command quit',
base.url = base.url)
}
# ------------------------------------------------------------------------------
#' @title Command Run File
#'
#' @description The run command will execute a command script from the file pointed
#' to by the file argument, which should contain Cytoscape commands, one per line.
#' Arguments to the script are provided by the args argument
#' @param file Path to command script file
#' @param args The script arguments as key:value pairs separated by commas
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples \donttest{
#' commandRunFile('/path/to/my/file.txt')
#' }
#' @export
commandRunFile <- function(file, args=NULL, base.url = .defaultBaseUrl){
args.str <- ""
if(!is.null(args))
args.str <- paste0(' args="',args,'"')
commandsPOST(paste0('command run',args.str,' file="',getAbsSandboxPath(file),'"'),
base.url = base.url)
}
# ------------------------------------------------------------------------------
#' @title Command Sleep
#'
#' @description The sleep command will pause processing for a period of time as
#' specified by duration seconds. It is typically used as part of a command script.
#' @param duration (optional) The time in seconds to sleep
#' @param base.url (optional) Ignore unless you need to specify a custom domain, #' port or version to connect to the CyREST API. Default is http://localhost:1234 #' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples \donttest{
#' commandSleep(5)
#' }
#' @export
commandSleep <- function(duration=NULL, base.url = .defaultBaseUrl){
dur.str <- ""
if(!is.null(duration))
dur.str <- paste0(' duration="',duration,'"')
commandsPOST(paste0('command sleep',dur.str),
base.url = base.url)
}
# ==============================================================================
# III. Internal functions
#
# Dev Notes: Prefix internal functions with a '.'. Do not @export and in general
# skip royxgen docs for these functions, with the exception of @importFrom lines.
# ------------------------------------------------------------------------------
# Command string to CyREST GET query URL
#
# @description Converts a command string to a CyREST GET query URL.
# @param cmd.string (char) command
# @param base.url cyrest base url for communicating with cytoscape
# @return CyREST GET URL
# @examples
# \donttest{
# .command2getQuery('layout get preferred')
# }
#' @importFrom utils URLencode
.command2getQuery<-function(cmd.string, base.url = .defaultBaseUrl){
cmd.string = sub(" ([A-Za-z0-9_-]*=)","XXXXXX\\1",cmd.string)
cmdargs = unlist(strsplit(cmd.string,"XXXXXX"))
cmd = cmdargs[1]
if(is.na(cmd)){cmd=""}
q.cmd = URLencode(paste(base.url, "commands", sub(" ","/",cmd), sep="/"))
args = cmdargs[2]
if (is.na(args)){
q.cmd
}else{
args = gsub("\"","",args)
p = "[A-Za-z0-9_-]+="
m = gregexpr(p,args)
args1 = unlist(regmatches(args,m))
args1 = gsub('=','',args1)
#args1 = unlist(str_extract_all(args,"[A-Za-z0-9_-]+(?==)")) # requires stringr lib
args2 = unlist(strsplit(args," *[A-Za-z0-9_-]+="))
args2 = args2[-1]
names(args2) <- args1
q.args = .prepGetQueryArgs(args2)
paste(q.cmd,q.args,sep="?")
}
}
# ------------------------------------------------------------------------------
# Command string to CyREST POST query URL
#
# @description Converts a command string to a CyREST POST query URL.
# @param cmd.string (char) command
# @param base.url cyrest base url for communicating with cytoscape
# @return CyREST POST URL
# @examples
# \donttest{
# .command2postQueryUrl('network clone network="current"')
# # http://localhost:1234/v1/commands/network/clone
# }
#' @importFrom utils URLencode
.command2postQueryUrl<-function(cmd.string, base.url = .defaultBaseUrl){
cmd.string = sub(" ([A-Za-z0-9_-]*=)","XXXXXX\\1",cmd.string)
cmdargs = unlist(strsplit(cmd.string,"XXXXXX"))
cmd = cmdargs[1]
if(is.na(cmd)){cmd=""}
URLencode(paste(base.url, "commands", sub(" ","/",cmd), sep="/"))
}
# ------------------------------------------------------------------------------
# Command string to CyREST POST query JSON body.
#
# @description Converts a command string to a CyREST POST query JSON body.
# @details POST requests require at leaset one arg, so a "filler" arg is provided if NULL
# @param cmd.string (char) command
# @param base.url cyrest base url for communicating with cytoscape
# @return CyREST POST JSON body
# @examples
# \donttest{
# .command2postQueryBody('network clone network="current"')
# # {
# # "network": "current"
# # }
# }
#' @importFrom RJSONIO toJSON
.command2postQueryBody<-function(cmd.string){
cmd.string = sub(" ([A-Za-z0-9_-]*=)","XXXXXX\\1",cmd.string)
cmdargs = unlist(strsplit(cmd.string,"XXXXXX"))
args = cmdargs[2]
if (is.na(args))
args = 'atLeastOneArg=required' #supply a benign "filler" if NULL
args = gsub("\"","",args)
p = "[A-Za-z0-9_-]+="
m = gregexpr(p,args)
args1 = unlist(regmatches(args,m))
args1 = gsub('=','',args1)
#args1 = unlist(str_extract_all(args,"[A-Za-z0-9_-]+(?==)")) # requires stringr lib
args2 = unlist(strsplit(args," *[A-Za-z0-9_-]+="))
args2 = args2[-1]
names(args2) <- args1
return(toJSON(args2))
}
# Takes a named list and makes a string for GET query urls
#' @importFrom utils URLencode
.prepGetQueryArgs <- function(named.args){
args1 <- names(named.args)
args2 <- unlist(unname(named.args))
q.args = paste(args1[1],URLencode(as.character(args2[1])),sep="=")
for (i in seq(args1)[-1]){
arg = paste(args1[i],URLencode(as.character(args2[i])),sep="=")
q.args = paste(q.args,arg,sep="&")
}
return(q.args)
}
# Parses all the possible list types and keywords accepted by Commands API.
# If column designation is supported, simply provide a column name; otherwise
# it is assumed to not be supported and returns a simple list.
.prepPostQueryLists <- function(cmd.list=NULL, cmd.by.col=NULL){
if (is.null(cmd.list)) {
cmd.list.ready = "selected" #need something here for edge selections to work
} else if (!is.null(cmd.by.col)) {
cmd.list.col = NULL
for (i in seq_len(length(cmd.list))) {
cmd.list.col[i] = paste(cmd.by.col, cmd.list[i], sep = ":")
}
cmd.list.ready = paste(cmd.list.col, collapse = ",")
} else {
cmd.list.ready = paste(cmd.list, collapse=",")
}
return(cmd.list.ready)
}
# ------------------------------------------------------------------------------
# CyRest Message Handler
#
# @description Provides helpful messaages for CyREST issues.
# @c Error condition
# @res Result with error
# @return A stop message
# @examples
# \donttest{
# tryCatch(
# res <- cyRestGET("version"),
# error=function(c) {.cyError(c, res)}
# )
#
.cyError<-function(c, res){
err_conn = 'Connection refused' # Connection Error
if (length(grep(err_conn,c$message)) == 0){ # Certain 404 Errors
stop(simpleError("Not Found"))
} else {
message("Oh no! I can't find Cytoscape. RCy3 can not continue!
Please check that Cytoscape is running, CyREST is installed and your base.url parameter is correct.")
write(sprintf("Failed to execute: %s",res[[1]]), stderr())
stop(simpleError(conditionMessage(c)))
}
}
.cyWarnings<-function(c, res){
#Pass along any warnings and carry on
message(c$message)
}
#' @importFrom RJSONIO fromJSON
#' @importFrom XML htmlParse xmlValue xpathSApply
.cyFinally<-function(res){
if(!is.null(res)){
# Check HTTP Errors
if(res$status_code == 414) {
print("URI Too Long: The command you attempted to execute is too large to be handled via GET request. Consider switching to commandsPost() for larger queries.")
}
if(res$status_code > 299){
write(sprintf("Failed to execute: %s",res[[1]]), stderr())
if(res[[3]]$`content-type` == "text/plain" ||
res[[3]]$`content-type` == "text/html;charset=iso-8859-1"){
errmsg <- paste(xpathSApply(htmlParse(rawToChar(res$content), asText=TRUE), "//p", xmlValue),
xpathSApply(htmlParse(rawToChar(res$content), asText=TRUE), "//pre", xmlValue))
stop(simpleError(errmsg))
} else if (res[[3]]$`content-type` == "application/json"){
stop(simpleError(RJSONIO::fromJSON(rawToChar(res$content))$errors[[1]]$message))
} else {
stop()
}
}
}
}
# ------------------------------------------------------------------------------
# Encode Operation
#
# Applies URLencode to each step along the URL path without clobbering the path.
.pathURLencode <- function(operation){
steps <- strsplit(operation,"\\/")[[1]]
paste(lapply(steps, URLencode, reserved = TRUE), collapse = "/")
}
# ==============================================================================
# IV. Jupyter-bridge
# ------------------------------------------------------------------------------
#' @title findRemoteCytoscape
#' @description Figure out whether CyREST is local or remote. If remote, we'll
#' want to go through Jupyter-Bridge.
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples
#' \donttest{
#' findRemoteCytoscape()
#' }
#' @export
findRemoteCytoscape<-function(base.url=.defaultBaseUrl){
checkNotebookIsRunning()
checkRunningRemote(base.url)
#doInitializeSandbox(requester, base.url=.defaultBaseUrl)
# make sure there's a sandbox before executing a command
if(is.null(checkRunningRemote(base.url))){
stop('Cannot find local or remote Cytoscape. Start Cytoscape and then proceed.')
}
return(runningRemoteCheck(base.url))
}
# ==============================================================================
# V. Sandbox
# ------------------------------------------------------------------------------
#' @title doInitializeSandbox
#' @description doInitializeSandbox
#' @param requester requester
#' @param base.url Ignore unless you need to specify a custom domain, port or
#' version to connect to the CyREST API. Default is http://127.0.0.1:1234 and
#' the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples
#' \donttest{
#' doInitializeSandbox()
#' }
#' @export
doInitializeSandbox <- function(requester=NULL, base.url = .defaultBaseUrl){
if(getSandboxReinitialize()){
return(doSetSandbox(.getDefaultSandbox(base.url), requester, base.url = base.url))
} else {
return(getCurrentSandbox())
}
}
# ------------------------------------------------------------------------------
#' @title doSetSandbox
#' @description doSetSandbox
#' @param sandboxToSet sandbox to set
#' @param requester requester
#' @param base.url Ignore unless you need to specify a custom domain, port or
#' version to connect to the CyREST API. Default is http://127.0.0.1:1234 and
#' the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples
#' \donttest{
#' doSetSandbox()
#' }
#' @importFrom glue glue
#' @export
doSetSandbox <- function(sandboxToSet, requester=NULL, base.url = .defaultBaseUrl){
requester <- .getRequester(base.url)
if(is.null(sandboxToSet[['sandboxName']])){
sandboxToSet[['sandboxName']] <- getDefaultSandbox()[['sandboxName']]
}
sandboxName <- sandboxToSet[['sandboxName']]
if(!is.null(sandboxName)){
tryCatch(
expr = {
if(!requester){
r <- POST(url=glue('{base.url}/commands/filetransfer/setSandbox'), body=sandboxToSet, encode="json", content_type_json())
newSandbox <- setCurrentSandbox(sandboxName, RJSONIO::fromJSON(rawToChar(r$content))$data[['sandboxPath']])
} else {
r <- doRequestRemote("POST", glue('{base.url}/commands/filetransfer/setSandbox'), qbody=sandboxToSet, headers=list("Content-Type" = "application/json"))
newSandbox <- setCurrentSandbox(sandboxName, RJSONIO::fromJSON(RJSONIO::fromJSON(rawToChar(r$content))$text)$data[['sandboxPath']])
}
},
error = function(e){
caller <- deparse(sys.call())
message <- RJSONIO::fromJSON(rawToChar(r$content))[['errors']]
stop(message, caller)
}
)
} else {
defaultSandboxPath <- getDefaultSandboxPath()
if(is.null(defaultSandboxPath)){
if(getNotebookIsRunning()){
tryCatch(
expr = {
if(!requester){
r <- POST(url=glue('{base.url}/commands/filetransfer/getFileInfo'), body=list('sandboxName' = NULL,'fileName' = '.'), encode="json", content_type_json())
defaultSandboxPath <- setDefaultSandboxPath(RJSONIO::fromJSON(rawToChar(r$content))$data[['filePath']])
} else {
r <- doRequestRemote("POST", glue('{base.url}/commands/filetransfer/getFileInfo'), qbody=list('sandboxName' = NULL,'fileName' = '.'), headers=list("Content-Type" = "application/json"))
defaultSandboxPath <- setDefaultSandboxPath(RJSONIO::fromJSON(RJSONIO::fromJSON(rawToChar(r$content))$text)$data[['filePath']])
}
},
error = function(e){
defaultSandboxPath <- NULL
print('Warning: FileTransfer app is not available, so sandbox operations will fail')
}
)
} else {
defaultSandboxPath <- getwd()
}
}
newSandbox <- setCurrentSandbox(NULL, defaultSandboxPath)
}
setSandboxReinitialize(FALSE)
return(newSandbox)
}
# ------------------------------------------------------------------------------
#' @title .getDefaultSandbox
#' @description .getDefaultSandbox
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples
#' \donttest{
#' .getDefaultSandbox()
#' }
.getDefaultSandbox <- function(base.url=.defaultBaseUrl){
default <- getDefaultSandbox()
if(length(default) == 0){
if(getNotebookIsRunning() || runningRemoteCheck(base.url)){
default <- sandboxInitializer(list(sandboxName=RCy3env$.predefinedSandboxName))
} else {
default <- sandboxInitializer(list(sandboxName=NULL))
}
setDefaultSandbox(default)
}
return(default)
}
# ------------------------------------------------------------------------------
#' @title .getRequester
#' @description .getRequester
#' @param base.url (optional) Ignore unless you need to specify a custom domain,
#' port or version to connect to the CyREST API. Default is http://localhost:1234
#' and the latest version of the CyREST API supported by this version of RCy3.
#' @return None
#' @examples
#' \donttest{
#' .getRequester()
#' }
.getRequester <- function(base.url=.defaultBaseUrl){
if(findRemoteCytoscape(base.url)){
return(TRUE)
} else {
return(FALSE)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.