Commit 5e5d8f98 authored by Matija Obreza's avatar Matija Obreza

Migrate to API v1

- Genesys filtering model is also updated
parent 995fd77a
# November 2019
Updated from Genesys API v0 calls to API v1.
Note: The filter structure has changed. See Tutorial.
# August 2019
Updated for API at api.genesys-pgr.org
......
......@@ -187,7 +187,7 @@ client_login <- function() {
#' @examples
#' api_url("/me")
api_url <- function(path) {
paste0(.genesysEnv$server, "/api/v0", path)
paste0(.genesysEnv$server, "/api/v1", path)
}
......@@ -237,8 +237,11 @@ api1_url <- function(path) {
Authorization = .genesysEnv$Authorization,
"Content-Type" = content.type
), body = content)
if (httr::status_code(resp) != 200) {
stop("Genesys responded with HTTP status code ", httr::status_code(resp), ". Expected 200. See response content:\n", httr::content(resp), call. = FALSE)
}
if (httr::http_type(resp) != "application/json") {
stop("API did not return json", call. = FALSE)
stop("API did not return JSON, but Content-Type: ", httr::content(resp), ". See response content:\n", httr::content(resp), call. = FALSE)
}
resp
}
......@@ -44,6 +44,8 @@ MCPD <- list(
#' @param DOI Accession DOI
#' @param ORIGCTY Country of origin
#' @param SAMPSTAT Biological status of sample
#' @param GENUS List of genera
#' @param SPECIES List of specific epithets (within specified genera)
#'
#' @examples
#' # Filter accessions from Mexico and Slovenia
......@@ -51,13 +53,15 @@ MCPD <- list(
#'
#'
#' @export
mcpd_filter <- function(filter = list(), DOI = NULL, ORIGCTY = NULL, SAMPSTAT = NULL) {
mcpd_filter <- function(filter = list(), DOI = NULL, ORIGCTY = NULL, SAMPSTAT = NULL, GENUS = NULL, SPECIES = NULL) {
f <- c(filter)
f <- filter_DOI(f, DOI)
f <- filter_ORIGCTY(f, ORIGCTY)
f <- filter_SAMPSTAT(f, SAMPSTAT)
f <- filter_GENUS(f, GENUS)
f <- filter_SPECIES(f, SPECIES)
f
}
......@@ -80,7 +84,7 @@ filter_DOI <- function(filter = list(), DOI) {
filter_ORIGCTY <- function(filter = list(), ORIGCTY) {
f <- c(filter)
if (!is.null(ORIGCTY)) {
f$orgCty.iso3 = c(f$orgCty.iso3, ORIGCTY)
f$countryOfOrigin$iso3 = c(f$countryOfOrigin$iso3, ORIGCTY)
}
f
}
......@@ -96,3 +100,29 @@ filter_SAMPSTAT <- function(filter = list(), SAMPSTAT) {
}
f
}
#' Add filter by genus
#' @param filter Existing filters (or blank list if not provided)
#' @param GENUS List of genera
#' @export
filter_GENUS <- function(filter = list(), GENUS) {
f <- c(filter)
if (!is.null(GENUS)) {
f$taxonomy$genus = c(f$taxonomy$genus, GENUS)
}
f
}
#' Add filter on specific epithet
#' @param filter Existing filters (or blank list if not provided)
#' @param SPECIES List of specific epithets
#' @export
filter_SPECIES <- function(filter = list(), SPECIES) {
f <- c(filter)
if (!is.null(SPECIES)) {
f$taxonomy$species = c(f$taxonomy$species, SPECIES)
}
f
}
......@@ -13,7 +13,6 @@
# limitations under the License.
#' Max pages to retrieve
#' @keywords internal
.MAX_ALLOWED_PAGES <- 500
#' Who am i?
......@@ -41,13 +40,9 @@ me <- function() {
#' }
#'
#' @return Paged data structure
#' @keywords internal
.fetch_accessions_page <- function(filters = list(), page = 0, size = 1000, selector = NULL) {
start_time <- as.numeric(as.numeric(Sys.time())*1000, digits=15)
resp <- .post(path = "/acn/filter", query=list(p = page, l = size), body = filters)
if (httr::status_code(resp) != 200) {
stop("Genesys responded with HTTP status code ", httr::status_code(resp), ". Expected 200.")
}
resp <- .post(path = "/acn/list", query=list(p = page, l = size), body = filters)
end_time <- as.numeric(as.numeric(Sys.time())*1000, digits=15)
paged <- jsonlite::fromJSON(httr::content(resp, "text"), simplifyVector = FALSE)
message(paste("Retrieved page", page + 1, "of", paged$totalPages, "with", paged$numberOfElements, "rows in", end_time - start_time, "ms."))
......
......@@ -35,14 +35,16 @@ The database is queried by providing a `filter` (see Filters below):
# Open a browser: login to Genesys and authorize access
genesysr::user_login()
# Retrieve all accession data for genus *Musa*
musa <- fetch_accessions(filters = list(taxonomy.genus = c('Musa')))
# Retrieve first 1000 accessions for genus *Musa*
musa <- fetch_accessions(filters = list(taxonomy = list(genus = c('Musa'))), at.least = 1000)
# Or retrieve all accession data for genus *Musa*
musa <- fetch_accessions(filters = list(taxonomy = list(genus = c('Musa'))))
# Retrieve all accession data for the Musa International Transit Center, Bioversity International
itc <- fetch_accessions(list(institute.code = c('BEL084')))
itc <- fetch_accessions(list(institute = list(code = c('BEL084'))))
# Retrieve all accession data for the Musa International Transit Center, Bioversity International (BEL084) and the International Center for Tropical Agriculture (COL003)
some <- fetch_accessions(list(institute.code = c('BEL084','COL003')))
some <- fetch_accessions(list(institute = list(code = c('BEL084','COL003'))))
```
**genesysr** provides utility functions to create `filter` objects using [Multi-Crop Passport Descriptors (MCPD)](https://www.genesys-pgr.org/documentation/basics) definitions:
......@@ -68,8 +70,14 @@ The records returned by Genesys match all filters provided (*AND* operation), wh
allow for specifying multiple criteria (*OR* operation):
```r
# (genus == Musa) AND ((origcty == NGA) OR (origcty == CIV))
filter <- list(taxonomy.genus = c('Musa'), orgCty.iso3 = c('NGA', 'CIV'))
# (GENUS == Musa) AND ((ORIGCTY == NGA) OR (ORIGCTY == CIV))
filter <- list(taxonomy = list(genus = c('Musa'), species = c('aa')), countryOfOrigin = list(iso3 = c('NGA', 'CIV')))
# OR
filter <- list();
filter$taxonomy$genus = c('Musa')
filter$taxonomy$species = c('aa')
filter$countryOfOrigin$iso3 = c('NGA', 'CIV')
```
There are a number of filtering options to retrieve current data from Genesys.
......@@ -79,25 +87,29 @@ specifies the criteria to match.
### Taxonomy
`taxonomy.genus` filters by a *list* of genera.
`taxonomy$genus` filters by a *list* of genera.
```r
filters <- list(taxonomy.genus = c('Hordeum', 'Musa'))
filters <- list(taxonomy = list(genus = c('Hordeum', 'Musa')))
# Print
jsonlite::toJSON(filters)
```
`taxonomy.species` filters by a *list* of species.
`taxonomy$species` filters by a *list* of species.
```r
filters <- list(taxonomy.genus = c('Hordeum'), taxonomy.species = c('vulgare'))
filters <- list(taxonomy = list(genus = c('Hordeum'), species = c('vulgare')))
# Print
jsonlite::toJSON(filters)
```
### Origin of material
`orgCty.iso3` filters by ISO3 code of country of origin of PGR material.
`countryOfOrigin$iso3` filters by ISO3 code of country of origin of PGR material.
```r
# Material originating from Germany (DEU) and France (FRA)
filters <- list(orgCty.iso3 = c('DEU', 'FRA'))
filters <- list(countryOfOrigin = list(iso3 = c('DEU', 'FRA')))
```
`geo.latitude` and `geo.longitude` filters by latitude/longitude (in decimal format) of the
......@@ -105,24 +117,24 @@ collecting site.
```r
# TBD
filters <- list(geo.latitude = genesysr::range(-10, 30), geo.longitude = genesysr::range(30, 50))
filters <- list(geo = list(latitude = genesysr::range(-10, 30), longitude = genesysr::range(30, 50)))
```
### Holding institute
`institute.code` filters by a *list* of FAO WIEWS institute codes of the holding institutes.
`institute$code` filters by a *list* of FAO WIEWS institute codes of the holding institutes.
```r
# Filter for ITC (BEL084) and CIAT (COL003)
list(institute.code = c('BEL084', 'COL003'))
list(institute = list(code = c('BEL084', 'COL003')))
```
`institute.country.iso3` filters by a *list* of ISO3 country codes of country of the holding institute.
`institute$country$iso3` filters by a *list* of ISO3 country codes of country of the holding institute.
```r
# Filter for genebanks in Slovenia (SVN) and Belgium (BEL)
list(institute.country.iso3 = c('SVN', 'BEL'))
list(institute = list(country = list(iso3 = c('SVN', 'BEL'))))
```
# Selecting columns
......@@ -132,8 +144,8 @@ To reduce the amount of data to be processed and kept in memory, select the colu
```
# Keep only accession id, acceNumb and instCode for *Musa* data
fetch_accessions(list(taxonomy.genus = c('Musa')), selector = function(x) {
list(id = x$id, acceNumb = x$acceNumb, instCode = x$institute$code)
fetch_accessions(list(taxonomy.genus = c('Musa')), at.least = 100, selector = function(x) {
list(id = x$id, acceNumb = x$accessionNumber, instCode = x$institute$code)
})
```
......@@ -141,7 +153,7 @@ To list the variable names returned by the Genesys APIs, test the response and s
```r
filters <- list()
accn <- fetch_accessions(filters)
accn <- fetch_accessions(filters, at.least = 100)
# Print names used in JSON response from Genesys
sort(unique(names(unlist(accn$content))))
......@@ -167,7 +179,7 @@ user_login()
3. Fetch data
```r
musa <- genesysr::fetch_accessions(list(taxonomy.genus = c('Musa')))
musa <- genesysr::fetch_accessions(list(taxonomy = list(genus = c('Musa'))), at.least = 1000)
```
4. Flatten data into data frame
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment