Skip to content

Instantly share code, notes, and snippets.

@yutannihilation
Last active April 6, 2020 15:22
Show Gist options
  • Save yutannihilation/b6a7c06704b2f5d9d0e5d2eead3b88af to your computer and use it in GitHub Desktop.
Save yutannihilation/b6a7c06704b2f5d9d0e5d2eead3b88af to your computer and use it in GitHub Desktop.
library(httr)

delika_new_jwt <- function() {
  # TODO
  browseURL("https://api.delika.io/v1/auth/token")
}

delika_verb <- function(verb, path, ...) {
  secret <- jsonlite::fromJSON("~/.delika/token.json")
  
  res <- httr::VERB(
    verb = verb,
    url = glue::glue("https://api.delika.io/v1{path}"),
    httr::add_headers(Authorization = glue::glue("bearer {secret$AccessToken}")),
    httr::config(followlocation = FALSE),
    ...
  )
  
  status_code <- httr::status_code(res)
  if (status_code >= 400) {
    body <- httr::content(res, "text")
    rlang::abort(glue::glue("Status: {status_code}\nBody: {body}"))
  }
  
  res
}

delika_refresh <- function() {
  secret <- jsonlite::fromJSON("~/.delika/token.json")
  
  res <- delika_verb("POST", "/auth/token",
                     body = list(RefreshToken = secret$RefreshToken),
                     encode = "json")
  
  secrets <- content(res)$Data
  if (is.null(secrets)) {
    rlang::abort("Something is wrong")
  }
  
  jsonlite::write_json(secrets, "~/.delika/token.json")
}

delika_refresh()

delika_list_datasets <- function(AccountName = NULL) {
  if (is.null(AccountName)) {
    AccountName <- "me"
  } else {
    AccountName <- paste0("account/", AccountName)
  }
  
  res <- delika_verb("GET", glue::glue("/{AccountName}/datasets"))
  l <- content(res)$Data$DatasetList
  dplyr::bind_rows(l)
}

delika_list_datasets()
#> # A tibble: 1 x 2
#>   AccountName     DatasetName     
#> * <chr>           <chr>           
#> 1 yutannihilation yahoodatacovid19
delika_list_datasets("kos59125")
#> # A tibble: 2 x 2
#>   AccountName DatasetName
#> * <chr>       <chr>      
#> 1 kos59125    random     
#> 2 kos59125    geodata

delika_list_data <- function(AccountName, DatasetName) {
  res <- delika_verb("GET", glue::glue("/dataset/{AccountName}/{DatasetName}/data"))
  l <- content(res)$Data$DataList
  dplyr::bind_rows(l)
}

delika_list_data("yutannihilation", "yahoodatacovid19")
#> # A tibble: 2 x 3
#>   AccountName     DatasetName      DataName            
#> * <chr>           <chr>            <chr>               
#> 1 yutannihilation yahoodatacovid19 data.csv            
#> 2 yutannihilation yahoodatacovid19 東京23区推移0403.csv

delika_get_data_schema <- function(AccountName, DatasetName, DataName) {
  res <- delika_verb("GET", glue::glue("/data/{AccountName}/{DatasetName}/{DataName}/metadata/schema"))
  jsonlite::fromJSON(content(res)$Data$Schema, simplifyDataFrame = TRUE)
}

delika_get_data_schema("yutannihilation", "yahoodatacovid19", "data.csv")
#> $SchemaVersion
#> [1] "1.0"
#> 
#> $TableDefinition
#> $TableDefinition$Columns
#>       Name DataType
#> 1     area     text
#> 2 category     text
#> 3  x__date     text
#> 4 visitors   number
#> 
#> 
#> $DataSpecification
#> $DataSpecification$FormatType
#> [1] "csv"
#> 
#> $DataSpecification$DeliveryType
#> [1] "file"
#> 
#> $DataSpecification$DataOptions
#> $DataSpecification$DataOptions$Header
#> [1] TRUE
#> 
#> $DataSpecification$DataOptions$Encoding
#> [1] "utf-8"
#> 
#> $DataSpecification$DataOptions$FieldDelimiter
#> [1] ","
#> 
#> $DataSpecification$DataOptions$NullString
#> [1] ""

delika_get_data <- function(AccountName, DatasetName, DataName) {
  # TODO: schema might be incorrect...
  schema <- delika_get_data_schema(AccountName, DatasetName, DataName)$TableDefinition$Columns
  col_spec <- purrr::map(schema$DataType$DataType, ~ switch(.x,
    "text"   = readr::col_character(),
    "number" = readr::col_double()
  ))
  names(col_spec) <- schema$Name
  
  res <- delika_verb("GET", glue::glue("/data/{AccountName}/{DatasetName}/{DataName}/rawdata"))
  loc <- res$headers$location
  
  tmp <- tempfile(fileext = ".csv.gz")
  on.exit(unlink(tmp))
  curl::curl_download(loc, tmp)
  readr::read_csv(tmp, col_types = col_spec)
}

delika_get_data("yutannihilation", "yahoodatacovid19", "data.csv")
#> Warning: The following named parsers don't match the column names: x__date
#> # A tibble: 2,852 x 4
#>    area     category `_date`    visitors
#>    <chr>    <chr>    <date>        <dbl>
#>  1 千代田区 住人     2020-02-01    54900
#>  2 千代田区 住人     2020-02-02    54900
#>  3 千代田区 住人     2020-02-03    54900
#>  4 千代田区 住人     2020-02-04    54900
#>  5 千代田区 住人     2020-02-05    54900
#>  6 千代田区 住人     2020-02-06    54900
#>  7 千代田区 住人     2020-02-07    54900
#>  8 千代田区 住人     2020-02-08    54900
#>  9 千代田区 住人     2020-02-09    54900
#> 10 千代田区 住人     2020-02-10    54900
#> # … with 2,842 more rows

Created on 2020-04-07 by the reprex package (v0.3.0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment