generator_script.R

### Generator script to generate most of the connections
### automatically from the SWAGGER API.
library(httr)
library(purrr)
library(glue)
swagger <- content(GET("https://api.ubiops.com/v2.1/swagger/"))

#swagger$info
base <- paste0("https://", swagger$host, swagger$basePath)
endpoints <- swagger$paths
# every point has a method (get, post, delete, etc)
# every method has complete documentation
# "operationId" "summary"     "description" "parameters"  "responses"   "tags"

endpoints_slugs <- names(endpoints)
calls <- map_int(endpoints, length)
source_material <- data.frame(
    endpoint = map2(endpoints_slugs, calls, rep) %>% flatten_chr(),
    verb = map(endpoints, names) %>% flatten_chr()
)

extract_thingy <- function(source_material, value){
    map2_chr(source_material$endpoint, source_material$verb,function(x,y){endpoints[[x]][[y]][[value]]  })
}
extract_list <- function(source_material, value){
    map2(source_material$endpoint, source_material$verb,function(x,y){endpoints[[x]][[y]][[value]]  })
}

source_material$operationId <- extract_thingy(source_material, "operationId")
source_material$summary <- extract_thingy(source_material, "summary")
source_material$description <- extract_thingy(source_material, "description")
source_material$parameters <- extract_list(source_material, "parameters")
source_material$responses <- extract_list(source_material, "responses")
source_material$tags <- extract_list(source_material, "tags")
source_material$slug <- sub("^(/[a-z]+/).+$", replacement = "\\1", source_material$endpoint )
# # set this at the start
# h <- add_headers("Authorization"=Sys.getenv("UBIOPS_TOKEN"))
# base="https://api.ubiops.com/v2.1"
# # generate something like this for every endpoint
#
# endpoint <- glue("{base}/projects/{project_name}/deployments")
#
# base/endpoint
# toupper(verb)
# POST(url=endpoint,body = body,encode = "json",h)
#

extract_parameter_names <- function(parameters){
    par_names <- c()
    for (i in seq_along(parameters)) {
        # if it contains schema go one deeper
        if(is.null(parameters[[i]][["schema"]])){
            par_names <- c(par_names, pluck(parameters[[i]], "name"))
        }else{
            par_names <- c(par_names, names(parameters[[i]][["schema"]][["properties"]]))
        }
    }
    par_names <- par_names[par_names != ""]
    gsub("-","_", unique(par_names))
}

parameter_description <- function(names){
    collection <- c()
    for (name in names){collection <- c(collection,  paste("#' @param", name, "descriptionhere") )}
    collection
}

### split dataset on /slug/ (first part), rscript per slug

### generate roxygen2 at top summary as title
### empty line
### description
### empty line
### operationId = operationId
### empty line
###
# extract the parameter names, could use that for
# roxygen description '@param name ( type )
#
# I can also use those to add the function()
#
# I could unpack the parameters, use the 'in' thingy to discovery where
# parameters should go, the path


#' generates text
generate_api_docs_and_code <- function(endpoint, verb, operationId, summary, description, parameters){
    functionname <- paste0(verb,"_",gsub("-","_",operationId))
    parameternames <- extract_parameter_names(parameters[[1]])
    parametervalues <- paste(paste(parameternames, collapse = ", "),'UBIOPS_TOKEN=NULL', sep = ", ",collapse = ", ")
    parametervalues <- parametervalues[!is.null(parametervalues)]
    c(
        "",
        glue("#' {summary}"),
        "#' ",
        paste("#' ", unlist(strsplit(description, "\n"))),
        "#'",
        parameter_description(parameternames),
        "#' @param UBIOPS_TOKEN default NULL will search for token in environment",
        "#' @return descriptionhere",
        "#' @export",
        paste0("uo_", functionname, " <- function(",parametervalues,'){' ),
        paste0("    endpoint=glue::glue(\"{base}",endpoint,"\")"),
        "        tk <- check_ubiobstoken(UBIOPS_TOKEN)",
        "        h  <- create_headers(tk)",
        "    body<-'somethinghere' ",
        glue("    res <- httr::{toupper(verb)}(url=endpoint,body=body,encode = \"json\",h)"),
        "    httr::stop_for_status(res)",
        "    httr::content(res)",
        "}"
    )
}

Create_files <- function(source_material){
    groups <- unique(source_material$slug)
    for (group in groups) {
        scriptname <- paste0("R/",gsub('/','',group),'.R')
        if(file.exists(scriptname)){file.remove(scriptname)}
        scriptcontent <- c("# (autogenerated content from swagger API)", "")
        dataset <- source_material[source_material$slug == group,]
        for (row in seq_len(nrow(dataset))) {
            functioncontent <- generate_api_docs_and_code(
                endpoint = dataset[row,'endpoint'],
                verb = dataset[row,'verb'],
                operationId = dataset[row,'operationId'],
                summary = dataset[row,'summary'],
                description = dataset[row,'description'],
                parameters = dataset[row,'parameters']
                )
            scriptcontent <- c(scriptcontent, functioncontent)
        }
        message(paste('generating', scriptname))
        writeLines(scriptcontent, scriptname)
    }
}

Create_files(source_material)

writeLines(
    c(
     "# utilities",
    "",
    'base="https://api.ubiops.com/v2.1"',
    "",
    "#' @noRd",
    "check_ubiobstoken <- function(UBIOPS_TOKEN=NULL){",
    "    if(is.null(UBIOPS_TOKEN)){",
    '        UBIOPS_TOKEN <- Sys.getenv("UBIOPS_TOKEN", unset=NA)',
    "    }",
    "    UBIOPS_TOKEN",
    "}",
    "",
    "create_headers <- function(UBIOPS_TOKEN=NULL){",
    '    httr::add_headers("Authorization"= UBIOPS_TOKEN)',
    "}"
    ),
    con = "R/utils.R"
)
RMHogervorst/ubiopscontroller documentation built on May 25, 2021, 5:26 p.m.