Skip to content

Commit

Permalink
More tweaks to UCSC.api.url() and its man page
Browse files Browse the repository at this point in the history
  • Loading branch information
hpages committed Apr 17, 2024
1 parent ec64714 commit c2aefbf
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 37 deletions.
21 changes: 13 additions & 8 deletions R/REST_API.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
## will silently return an NA (see ?httr::content). This happens for
## example with the following query:
## query <- list(genome="eboVir3", track="iedbBcell")
## .API_query("getData/track", query=query)
## .query_API("getData/track", query=query)
## This query returns a response with bytes 233 (\xe9) and 246 (\xf6)
## in response$content. These bytes cause the call to content() below
## to silently return an NA.
Expand All @@ -36,10 +36,10 @@
## details about the error.
## Error 400 happens for example with the following query:
## query <- list(genome="mm9", track="chainNetBosTau6Viewnet")
## .API_query("getData/track", query=query)
## .query_API("getData/track", query=query)
## Error 415 happens for example with the following query:
## query <- list(genome="mm9", track="bamMmsNumtSSorted")
## .API_query("getData/track", query=query)
## .query_API("getData/track", query=query)
if (status_code %in% c(400L, 415L)) {
parsed_json <- .parse_json(response)
stop(wmsg("[HTTP ", status_code, "] ",
Expand All @@ -54,7 +54,7 @@
}

### Returns the parsed JSON content of the response.
.API_query <- function(endpoint, query=list(), api.url=UCSC.api.url(),
.query_API <- function(endpoint, query=list(), api.url=UCSC.api.url(),
fallback_errmsg=NULL)
{
stopifnot(isSingleString(endpoint), nzchar(endpoint),
Expand Down Expand Up @@ -84,9 +84,11 @@
### Endpoint /list/ucscGenomes
API_list_genomes <- function(api.url=UCSC.api.url())
{
api.url <- normarg_api.url(api.url)

endpoint <- "list/ucscGenomes"
fallback_errmsg <- c("failed to get list of UCSC genomes from ", api.url)
parsed_json <- .API_query(endpoint, api.url=api.url,
parsed_json <- .query_API(endpoint, api.url=api.url,
fallback_errmsg=fallback_errmsg)
ans <- parsed_json[["ucscGenomes"]]
## Sanity check.
Expand All @@ -98,12 +100,13 @@ API_list_genomes <- function(api.url=UCSC.api.url())
API_list_chromosomes <- function(genome, api.url=UCSC.api.url())
{
stopifnot(isSingleString(genome), nzchar(genome))
api.url <- normarg_api.url(api.url)

endpoint <- "list/chromosomes"
query <- list(genome=genome)
fallback_errmsg <- c(genome, ": unknown UCSC genome ",
"(or ", api.url, " is down?)")
parsed_json <- .API_query(endpoint, query=query, api.url=api.url,
parsed_json <- .query_API(endpoint, query=query, api.url=api.url,
fallback_errmsg=fallback_errmsg)
## Sanity check.
stopifnot(identical(parsed_json[["genome"]], genome))
Expand All @@ -114,12 +117,13 @@ API_list_chromosomes <- function(genome, api.url=UCSC.api.url())
API_list_tracks <- function(genome, api.url=UCSC.api.url())
{
stopifnot(isSingleString(genome), nzchar(genome))
api.url <- normarg_api.url(api.url)

endpoint <- "list/tracks"
query <- list(genome=genome)
fallback_errmsg <- c(genome, ": unknown UCSC genome ",
"(or ", api.url, " is down?)")
parsed_json <- .API_query(endpoint, query=query, api.url=api.url,
parsed_json <- .query_API(endpoint, query=query, api.url=api.url,
fallback_errmsg=fallback_errmsg)
ans <- parsed_json[[genome]]
## Sanity check.
Expand All @@ -135,13 +139,14 @@ API_get_track_data <- function(genome, primary_table, api.url=UCSC.api.url())
{
stopifnot(isSingleString(genome), nzchar(genome),
isSingleString(primary_table), nzchar(primary_table))
api.url <- normarg_api.url(api.url)

endpoint <- "getData/track"
query <- list(genome=genome, track=primary_table)
fallback_errmsg <- c(genome, "/", primary_table, ": ",
"unknown UCSC genome/primary_table ",
"(or ", api.url, " is down?)")
parsed_json <- .API_query(endpoint, query=query, api.url=api.url,
parsed_json <- .query_API(endpoint, query=query, api.url=api.url,
fallback_errmsg=fallback_errmsg)
## Sanity checks.
stopifnot(identical(parsed_json[["genome"]], genome))
Expand Down
50 changes: 42 additions & 8 deletions R/UCSC.api.url.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,51 @@
### -------------------------------------------------------------------------
###

### See https://genome.ucsc.edu/goldenPath/help/api.html#Mirrors
.UCSC_API_URLS <- c(
primary="https://api.genome.ucsc.edu", # primary URL (West Coast)
europe="https://genome-euro.ucsc.edu/cgi-bin/hubApi",
asia="https://genome-asia.ucsc.edu/cgi-bin/hubApi"
)

UCSC.api.url <- function(url=NULL)
.pattern2url <- function(pattern)
{
if (!nzchar(pattern))
return(.UCSC_API_URLS["primary"])
aliases <- names(.UCSC_API_URLS)
idx <- grep(pattern, aliases, ignore.case=TRUE)
if (length(idx) == 0L) {
in1string <- paste0("\"", c("", aliases), "\"")
in1string[[length(in1string)]] <-
paste0("or ", in1string[[length(in1string)]])
in1string <- paste(in1string, collapse=", ")
stop(wmsg("'api.url' must start with \"https://\" (or \"http://\") ",
"or match alias ", in1string))
}
if (length(idx) > 1L) {
in1string <- paste0("\"", aliases[idx], "\"", collapse=" and ")
stop(wmsg("\"", tolower(pattern), "\" matches more than ",
"one alias (", in1string, ")"))
}
.UCSC_API_URLS[idx]
}

normarg_api.url <- function(api.url)
{
if (!isSingleString(api.url))
stop(wmsg("'api.url' must be a single string"))
if (grepl("^https?://", api.url, ignore.case=TRUE))
return(api.url)
.pattern2url(api.url)
}

UCSC.api.url <- function(api.url=NULL)
{
ans <- getOption("UCSC.api.url")
if (is.null(url))
if (is.null(api.url))
return(ans)
if (!(isSingleString(url) && nzchar(url)))
stop(wmsg("'url' must be a single (non-empty) string"))
if (!startsWith(tolower(url), "http"))
stop(wmsg("'url' must start with \"http\""))
options(UCSC.api.url=url)
invisible(ans) # return old URL invisibly
api.url <- normarg_api.url(api.url)
options(UCSC.api.url=api.url)
invisible(ans) # return previous URL invisibly
}

7 changes: 2 additions & 5 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
.onLoad <- function(libname, pkgname)
{
## Alternative UCSC API URLs:
## - Europe: https://genome-euro.ucsc.edu/cgi-bin/hubApi
## - Asia: https://genome-asia.ucsc.edu/cgi-bin/hubApi
## - Mirror installation: https://your.server.edu/cgi-bin/hubApi
UCSC.api.url("https://api.genome.ucsc.edu") # primary URL (West Coast)
## Set global option "UCSC.api.url" to primary URL (West Coast).
UCSC.api.url("primary")
}

48 changes: 32 additions & 16 deletions man/UCSC.api.url.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,52 @@
}

\usage{
UCSC.api.url(url=NULL)
UCSC.api.url(api.url=NULL)
}

\arguments{
\item{url}{
Alternative UCSC API URL to use by default.
\item{api.url}{
A single string containing the URL to the alternative UCSC API to use
by default.

For convenience, \code{api.url} can also be one of the following aliases:
\itemize{
\item \code{"primary"}: alias for \code{"https://api.genome.ucsc.edu"}
(primary URL, US West Coast);
\item \code{""}: same as \code{"primary"};
\item \code{"europe"}: alias for
\code{"https://genome-euro.ucsc.edu/cgi-bin/hubApi"}
(Europe mirror);
\item \code{"asia"}: alias for
\code{"https://genome-asia.ucsc.edu/cgi-bin/hubApi"}
(Asia mirror).
}
}
}

\details{
Various functions in the \pkg{UCSC.utils} package query the UCSC REST API.
This is the case for example for \code{\link{list_UCSC_genomes}},
\code{\link{get_UCSC_chrom_sizes}}, \code{\link{list_UCSC_tracks}}
and others.
and more.

Global option \code{UCSC.api.url} controls the UCSC API URL
that these functions use y default. The option is set to
\code{"https://api.genome.ucsc.edu"} at package startup.
\code{"https://api.genome.ucsc.edu"} (primary URL, US West Coast)
at package startup.

\code{UCSC.api.url()} and \code{UCSC.api.url(url)} are provided
\code{UCSC.api.url()} and \code{UCSC.api.url(some_url)} are provided
as convenient ways of doing \code{getOption("UCSC.api.url")}
and \code{options(UCSC.api.url=url)}, respectively.
and \code{options(UCSC.api.url=some_url)}, respectively.
}

\value{
When called with no argument, \code{UCSC.api.url()} returns
\code{getOption("UCSC.api.url")}.

When passed an URL, \code{UCSC.api.url(url)} returns the \emph{old} URL,
that is, the UCSC API URL that was previously used by default. Note
that the \emph{old} URL is returned invisibly.
When passed an URL, \code{UCSC.api.url(some_url)} returns the
\emph{previous} URL, that is, the UCSC API URL that was previously
used by default. Note that the previous URL is returned invisibly.
}

\seealso{
Expand All @@ -55,14 +70,15 @@ UCSC.api.url(url=NULL)
UCSC.api.url() # current default value of the UCSC API URL
get_UCSC_chrom_sizes("ce11", recache=TRUE)

## Temporarily use the mirror in Asia:
old_url <- UCSC.api.url("https://genome-asia.ucsc.edu/cgi-bin/hubApi")
## Temporarily use the mirror in Europe:
previous_url <- UCSC.api.url("europe")
UCSC.api.url() # new default value of the UCSC API URL
\donttest{

get_UCSC_chrom_sizes("ce11", recache=TRUE)
}
## Restore old default value:
UCSC.api.url(old_url)

## Restore previous default value:
UCSC.api.url(previous_url)
UCSC.api.url()
}

\keyword{manip}

0 comments on commit c2aefbf

Please sign in to comment.