1 getAPIDocument <- function(){
2 url <- "https://4xphq.arvadosapi.com/discovery/v1/apis/arvados/v1/rest"
3 serverResponse <- httr::RETRY("GET", url = url)
5 httr::content(serverResponse, as = "parsed", type = "application/json")
9 generateAPI <- function()
11 #TODO: Consider passing discovery document URL as parameter.
12 #TODO: Consider passing location where to create new files.
13 discoveryDocument <- getAPIDocument()
15 methodResources <- discoveryDocument$resources
16 resourceNames <- names(methodResources)
18 doc <- generateMethodsDocumentation(methodResources, resourceNames)
19 arvadosAPIHeader <- generateAPIClassHeader()
20 arvadosClassMethods <- generateClassContent(methodResources, resourceNames)
21 arvadosAPIFooter <- generateAPIClassFooter()
23 arvadosClass <- c(doc,
28 fileConn <- file("./R/Arvados.R", "w")
29 writeLines(unlist(arvadosClass), fileConn)
34 generateAPIClassHeader <- function()
37 "Arvados <- R6::R6Class(",
43 "\t\tinitialize = function(authToken = NULL, hostName = NULL, numRetries = 0)",
45 "\t\t\tif(!is.null(hostName))",
46 "\t\t\t\tSys.setenv(ARVADOS_API_HOST = hostName)",
48 "\t\t\tif(!is.null(authToken))",
49 "\t\t\t\tSys.setenv(ARVADOS_API_TOKEN = authToken)",
51 "\t\t\thostName <- Sys.getenv(\"ARVADOS_API_HOST\")",
52 "\t\t\ttoken <- Sys.getenv(\"ARVADOS_API_TOKEN\")",
54 "\t\t\tif(hostName == \"\" | token == \"\")",
55 "\t\t\t\tstop(paste(\"Please provide host name and authentification token\",",
56 "\t\t\t\t\t\t \"or set ARVADOS_API_HOST and ARVADOS_API_TOKEN\",",
57 "\t\t\t\t\t\t \"environment variables.\"))",
59 "\t\t\tprivate$token <- token",
60 "\t\t\tprivate$host <- paste0(\"https://\", hostName, \"/arvados/v1/\")",
61 "\t\t\tprivate$numRetries <- numRetries",
62 "\t\t\tprivate$REST <- RESTService$new(token, hostName,",
63 "\t\t\t HttpRequest$new(), HttpParser$new(),",
69 generateClassContent <- function(methodResources, resourceNames)
71 arvadosMethods <- Map(function(resource, resourceName)
73 methodNames <- names(resource$methods)
75 functions <- Map(function(methodMetaData, methodName)
77 methodName <- paste0(resourceName, ".", methodName)
78 createMethod(methodName, methodMetaData)
80 }, resource$methods, methodNames)
82 unlist(unname(functions))
84 }, methodResources, resourceNames)
89 generateAPIClassFooter <- function()
91 c("\t\tgetHostName = function() private$host,",
92 "\t\tgetToken = function() private$token,",
93 "\t\tsetRESTService = function(newREST) private$REST <- newREST,",
94 "\t\tgetRESTService = function() private$REST",
102 "\t\tnumRetries = NULL",
105 "\tcloneable = FALSE",
109 createMethod <- function(name, methodMetaData)
111 args <- getMethodArguments(methodMetaData)
112 signature <- getMethodSignature(name, args)
113 body <- getMethodBody(methodMetaData)
121 #TODO: Make sure that arguments that are required always go first.
122 # This is not the case if request$required is false.
123 getMethodArguments <- function(methodMetaData)
125 request <- methodMetaData$request
128 if(!is.null(request))
130 resourceName <- tolower(request$properties[[1]][[1]])
133 requestArgs <- resourceName
135 requestArgs <- paste(resourceName, "=", "NULL")
138 argNames <- names(methodMetaData$parameters)
140 args <- sapply(argNames, function(argName)
142 arg <- methodMetaData$parameters[[argName]]
146 if(!is.null(arg$default))
147 return(paste0(argName, " = ", "\"", arg$default, "\""))
149 return(paste(argName, "=", "NULL"))
158 getMethodSignature <- function(methodName, args)
160 collapsedArgs <- paste0(args, collapse = ", ")
161 lineLengthLimit <- 40
163 if(nchar(collapsedArgs) > lineLengthLimit)
165 return(paste0("\t\t",
166 formatArgs(paste(methodName, "= function("),
167 "\t", args, ")", lineLengthLimit)))
171 return(paste0("\t\t", methodName, " = function(", collapsedArgs, ")"))
175 getMethodBody <- function(methodMetaData)
177 url <- getRequestURL(methodMetaData)
178 headers <- getRequestHeaders()
179 requestQueryList <- getRequestQueryList(methodMetaData)
180 requestBody <- getRequestBody(methodMetaData)
181 request <- getRequest(methodMetaData)
182 response <- getResponse(methodMetaData)
183 errorCheck <- getErrorCheckingCode()
184 returnStatement <- getReturnObjectValidationCode()
188 requestQueryList, "",
190 request, response, "",
194 paste0("\t\t\t", body)
197 getRequestURL <- function(methodMetaData)
199 endPoint <- methodMetaData$path
200 endPoint <- stringr::str_replace_all(endPoint, "\\{", "${")
201 url <- c(paste0("endPoint <- stringr::str_interp(\"", endPoint, "\")"),
202 paste0("url <- paste0(private$host, endPoint)"))
206 getRequestHeaders <- function()
208 c("headers <- list(Authorization = paste(\"OAuth2\", private$token), ",
209 " \"Content-Type\" = \"application/json\")")
212 getRequestQueryList <- function(methodMetaData)
214 queryArgs <- names(Filter(function(arg) arg$location == "query",
215 methodMetaData$parameters))
217 if(length(queryArgs) == 0)
218 return("queryArgs <- NULL")
220 queryArgs <- sapply(queryArgs, function(arg) paste0(arg, " = ", arg))
221 collapsedArgs <- paste0(queryArgs, collapse = ", ")
223 lineLengthLimit <- 40
225 if(nchar(collapsedArgs) > lineLengthLimit)
226 return(formatArgs("queryArgs <- list(", "\t\t\t\t ", queryArgs, ")",
229 return(paste0("queryArgs <- list(", collapsedArgs, ")"))
232 getRequestBody <- function(methodMetaData)
234 request <- methodMetaData$request
236 if(is.null(request) || !request$required)
237 return("body <- NULL")
239 resourceName <- tolower(request$properties[[1]][[1]])
241 requestParameterName <- names(request$properties)[1]
243 c(paste0("if(length(", resourceName, ") > 0)"),
244 paste0("\tbody <- jsonlite::toJSON(list(", resourceName, " = ", resourceName, "), "),
245 "\t auto_unbox = TRUE)",
250 getRequest <- function(methodMetaData)
252 method <- methodMetaData$httpMethod
253 c(paste0("response <- private$REST$http$exec(\"", method, "\", url, headers, body,"),
254 " queryArgs, private$numRetries)")
257 getResponse <- function(methodMetaData)
259 "resource <- private$REST$httpParser$parseJSONResponse(response)"
262 getErrorCheckingCode <- function()
264 c("if(!is.null(resource$errors))",
265 "\tstop(resource$errors)")
268 getReturnObjectValidationCode <- function()
273 #NOTE: Arvados class documentation:
275 generateMethodsDocumentation <- function(methodResources, resourceNames)
277 methodsDoc <- unlist(unname(Map(function(resource, resourceName)
279 methodNames <- names(resource$methods)
281 methodDoc <- Map(function(methodMetaData, methodName)
283 methodName <- paste0(resourceName, ".", methodName)
284 getMethodDocumentation(methodName, methodMetaData)
286 }, resource$methods, methodNames)
288 unlist(unname(methodDoc))
290 }, methodResources, resourceNames)))
295 getMethodDocumentation <- function(methodName, methodMetaData)
297 name <- paste("#' @name", methodName)
298 usage <- getMethodUsage(methodName, methodMetaData)
299 description <- paste("#'", methodName, "is a method defined in Arvados class.")
300 params <- getMethodDescription(methodMetaData)
301 returnValue <- paste("#' @return", methodMetaData$response[["$ref"]], "object.")
313 getMethodUsage <- function(methodName, methodMetaData)
315 lineLengthLimit <- 40
316 args <- getMethodArguments(methodMetaData)
317 c(formatArgs(paste0("#' @usage arv$", methodName,
318 "("), "#' \t", args, ")", lineLengthLimit))
321 getMethodDescription <- function(methodMetaData)
323 request <- methodMetaData$request
326 if(!is.null(request))
328 requestDoc <- unname(unlist(sapply(request$properties, function(prop)
330 className <- sapply(prop, function(ref) ref)
331 objectName <- paste0(tolower(substr(className, 1, 1)),
332 substr(className, 2, nchar(className)))
333 paste("#' @param", objectName, className, "object.")
337 argNames <- names(methodMetaData$parameters)
339 argsDoc <- unname(unlist(sapply(argNames, function(argName)
341 arg <- methodMetaData$parameters[[argName]]
342 argDescription <- arg$description
343 paste("#' @param", argName, argDescription)
346 c(requestDoc, argsDoc)
349 #NOTE: Utility functions:
351 formatArgs <- function(prependAtStart, prependToEachSplit,
352 args, appendAtEnd, lineLength)
356 args[1:(length(args) - 1)] <- paste0(args[1:(length(args) - 1)], ",")
359 args[1] <- paste0(prependAtStart, args[1])
360 args[length(args)] <- paste0(args[length(args)], appendAtEnd)
362 argsLength <- length(args)
366 while(index <= argsLength)
371 while(nchar(line) < lineLength && index <= argsLength)
373 line <- paste(line, args[index])
377 argLines <- c(argLines, line)
380 argLines <- unlist(argLines)
381 argLinesLen <- length(argLines)
384 argLines[2:argLinesLen] <- paste0(prependToEachSplit, argLines[2:argLinesLen])