library(tidyverse)
## ── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
## ✔ ggplot2 3.3.1 ✔ purrr 0.3.4
## ✔ tibble 3.0.6 ✔ dplyr 1.0.4
## ✔ tidyr 1.1.0 ✔ stringr 1.4.0
## ✔ readr 1.3.1 ✔ forcats 0.5.0
## ── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(jsonlite)
##
## Attaching package: 'jsonlite'
## The following object is masked from 'package:purrr':
##
## flatten
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
This section lists some examples of public HTTP APIs that publish data in JSON format. These are great to get a sense of the complex structures that are encountered in real world JSON data.
See also https://github.com/public-apis/public-apis for a list of public APIs.
A single public API that shows location, status and current availability for all stations in the New York City bike sharing imitative. https://www.citibikenyc.com/system-data
citibike <- fromJSON("https://gbfs.citibikenyc.com/gbfs/en/station_status.json")
citibike$data$stations
## num_bikes_disabled is_returning last_reported is_renting station_id
## 1 3 1 1614231603 1 72
## 2 0 1 1614222616 1 79
## 3 2 1 1614234378 1 82
## 4 0 1 1614234376 1 83
## 5 3 1 1614233781 1 116
## 6 1 1 1614234375 1 119
## 7 0 1 1614234375 1 120
## 8 1 1 1614235584 1 127
## 9 3 1 1614235583 1 128
## 10 2 1 1614234376 1 143
## 11 0 1 1614233120 1 144
## 12 1 1 1614234376 1 146
## 13 1 1 1614232473 1 150
## 14 3 1 1614236349 1 151
## 15 1 1 1614222888 1 152
## station_status num_docks_disabled is_installed num_ebikes_available
## 1 active 0 1 2
## 2 active 0 1 0
## 3 active 0 1 2
## 4 active 0 1 1
## 5 active 0 1 0
## 6 active 0 1 4
## 7 active 0 1 1
## 8 active 0 1 2
## 9 active 0 1 0
## 10 active 0 1 1
## 11 active 0 1 4
## 12 active 0 1 2
## 13 active 0 1 5
## 14 active 0 1 1
## 15 active 0 1 0
## num_bikes_available num_docks_available eightd_has_available_keys legacy_id
## 1 17 35 FALSE 72
## 2 5 28 FALSE 79
## 3 18 7 FALSE 82
## 4 31 31 FALSE 83
## 5 6 41 FALSE 116
## 6 18 34 FALSE 119
## 7 3 16 FALSE 120
## 8 14 16 FALSE 127
## 9 15 38 FALSE 128
## 10 3 19 FALSE 143
## 11 51 7 FALSE 144
## 12 16 22 FALSE 146
## 13 25 30 FALSE 150
## 14 5 25 FALSE 151
## 15 9 39 FALSE 152
## [ reached 'max' / getOption("max.print") -- omitted 1350 rows ]
with_tz(as_datetime(citibike$last_updated), "US/Pacific")
## [1] "2021-02-24 23:03:55 PST"
citibike %>% glimpse()
## List of 3
## $ data :List of 1
## ..$ stations:'data.frame': 1365 obs. of 13 variables:
## .. ..$ num_bikes_disabled : int [1:1365] 3 0 2 0 3 1 0 1 3 2 ...
## .. ..$ is_returning : int [1:1365] 1 1 1 1 1 1 1 1 1 1 ...
## .. ..$ last_reported : int [1:1365] 1614231603 1614222616 1614234378 1614234376 1614233781 1614234375 1614234375 1614235584 1614235583 1614234376 ...
## .. ..$ is_renting : int [1:1365] 1 1 1 1 1 1 1 1 1 1 ...
## .. ..$ station_id : chr [1:1365] "72" "79" "82" "83" ...
## .. ..$ station_status : chr [1:1365] "active" "active" "active" "active" ...
## .. ..$ num_docks_disabled : int [1:1365] 0 0 0 0 0 0 0 0 0 0 ...
## .. ..$ is_installed : int [1:1365] 1 1 1 1 1 1 1 1 1 1 ...
## .. ..$ num_ebikes_available : int [1:1365] 2 0 2 1 0 4 1 2 0 1 ...
## .. ..$ num_bikes_available : int [1:1365] 17 5 18 31 6 18 3 14 15 3 ...
## .. ..$ num_docks_available : int [1:1365] 35 28 7 31 41 34 16 16 38 19 ...
## .. ..$ eightd_has_available_keys: logi [1:1365] FALSE FALSE FALSE FALSE FALSE FALSE ...
## .. ..$ legacy_id : chr [1:1365] "72" "79" "82" "83" ...
## $ last_updated: int 1614236635
## $ ttl : int 5
stations <- citibike$data$stations
good_stations <- stations %>%
filter(num_bikes_available > 0) %>%
select(station_id, num_bikes_available)
nrow(good_stations)
## [1] 1274
station_info <- fromJSON("https://gbfs.citibikenyc.com/gbfs/en/station_information.json")
station_info$data$stations %>%
inner_join(good_stations, by = "station_id") %>%
select(station_id, name, num_bikes_available)
## station_id name num_bikes_available
## 1 72 W 52 St & 11 Ave 17
## 2 79 Franklin St & W Broadway 5
## 3 82 St James Pl & Pearl St 18
## 4 83 Atlantic Ave & Fort Greene Pl 31
## 5 116 W 17 St & 8 Ave 6
## 6 119 Park Ave & St Edwards St 18
## 7 120 Lexington Ave & Classon Ave 3
## 8 127 Barrow St & Hudson St 14
## 9 128 MacDougal St & Prince St 15
## 10 143 Clinton St & Joralemon St 3
## 11 144 Nassau St & Navy St 51
## 12 146 Hudson St & Reade St 16
## 13 150 E 2 St & Avenue C 25
## 14 151 Cleveland Pl & Spring St 5
## 15 152 Warren St & W Broadway 9
## 16 153 E 40 St & 5 Ave 29
## 17 157 Henry St & Atlantic Ave 12
## 18 161 LaGuardia Pl & W 3 St 22
## 19 164 E 47 St & 2 Ave 10
## 20 168 W 18 St & 6 Ave 29
## 21 173 Broadway & W 49 St 24
## 22 174 E 25 St & 1 Ave 5
## 23 212 W 16 St & The High Line 30
## 24 216 Columbia Heights & Cranberry St 2
## 25 217 Old Fulton St 31
## 26 223 W 13 St & 7 Ave 22
## 27 224 Spruce St & Nassau St 4
## 28 228 E 48 St & 3 Ave 34
## 29 229 Great Jones St 1
## 30 232 Cadman Plaza E & Tillary St 10
## 31 236 St Marks Pl & 2 Ave 21
## 32 237 E 11 St & 2 Ave 21
## 33 238 Bank St & Washington St 10
## 34 239 Willoughby St & Fleet St 7
## 35 241 DeKalb Ave & S Portland Ave 1
## 36 244 Willoughby Ave & Hall St 4
## 37 245 Myrtle Ave & St Edwards St 13
## 38 247 Perry St & Bleecker St 52
## 39 248 Laight St & Hudson St 12
## 40 249 Harrison St & Hudson St 5
## 41 250 Lafayette St & Jersey St 18
## 42 251 Mott St & Prince St 8
## 43 252 MacDougal St & Washington Sq 19
## 44 254 W 11 St & 6 Ave 4
## 45 257 Lispenard St & Broadway 43
## 46 258 DeKalb Ave & Vanderbilt Ave 4
## 47 259 South St & Whitehall St 24
## 48 260 Broad St & Bridge St 21
## 49 261 Johnson St & Gold St 19
## 50 262 Washington Park 7
## 51 264 Maiden Ln & Pearl St 22
## 52 265 Stanton St & Chrystie St 21
## 53 267 Broadway & W 36 St 32
## 54 268 Howard St & Centre St 2
## 55 270 Adelphi St & Myrtle Ave 15
## 56 274 Lafayette Ave & Fort Greene Pl 15
## 57 275 Washington Ave & Greene Ave 7
## 58 276 Duane St & Greenwich St 6
## 59 278 Concord St & Bridge St 7
## 60 281 Grand Army Plaza & Central Park S 38
## 61 282 Kent Ave & S 11 St 11
## 62 284 Greenwich Ave & 8 Ave 20
## 63 285 Broadway & E 14 St 27
## 64 289 Monroe St & Classon Ave 4
## 65 291 Madison St & Montgomery St 17
## 66 293 Lafayette St & E 8 St 7
## [ reached 'max' / getOption("max.print") -- omitted 1208 rows ]
# davis
url <- str_glue(
"https://api.onwater.io/api/v1/results/{lat},{long}",
lat = 38.54491,
long = -121.74052)
fromJSON(url)
## $query
## [1] "38.54491,-121.74052"
##
## $request_id
## [1] "1ac43377-7f18-4c6a-9dba-88be85bad6c4"
##
## $lat
## [1] 38.54491
##
## $lon
## [1] -121.7405
##
## $water
## [1] FALSE
# lake tahoe
url <- str_glue(
"https://api.onwater.io/api/v1/results/{lat},{long}",
lat = 39.0968,
long = -120.0324)
fromJSON(url)
## $query
## [1] "39.0968,-120.0324"
##
## $request_id
## [1] "ff2cfeef-0c16-4262-a1fc-061a613a252e"
##
## $lat
## [1] 39.0968
##
## $lon
## [1] -120.0324
##
## $water
## [1] TRUE
It is a very simple API which suffles cards.
# get a deck
deck <- fromJSON("https://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=1")
# draw two cards
cards <- fromJSON(
str_glue("https://deckofcardsapi.com/api/deck/{deck_id}/draw/?count={count}",
deck_id = deck$deck_id, count = 2
),
flatten = TRUE
)
knitr::include_graphics(cards$cards$images.svg)
# reshuffle deck
fromJSON(
str_glue("https://deckofcardsapi.com/api/deck/{deck_id}/shuffle/",
deck_id = deck$deck_id
)
)
## $success
## [1] TRUE
##
## $deck_id
## [1] "qqhkt1wmn8ku"
##
## $remaining
## [1] 52
##
## $shuffled
## [1] TRUE
The parameters after ?
are called GET parameters. A more formal way to handle GET parameters is to use the httr
package.
library(httr)
endpoint <- str_glue("https://deckofcardsapi.com/api/deck/{deck_id}/draw/", deck_id = deck$deck_id)
r <- GET(endpoint, query = list(count = 2))
stop_for_status(r)
cards <- fromJSON(content(r, as = "text", encoding = "UTF-8"), flatten = TRUE)
cards
## $success
## [1] TRUE
##
## $deck_id
## [1] "qqhkt1wmn8ku"
##
## $cards
## code image value suit
## 1 5D https://deckofcardsapi.com/static/img/5D.png 5 DIAMONDS
## 2 6D https://deckofcardsapi.com/static/img/6D.png 6 DIAMONDS
## images.svg
## 1 https://deckofcardsapi.com/static/img/5D.svg
## 2 https://deckofcardsapi.com/static/img/6D.svg
## images.png
## 1 https://deckofcardsapi.com/static/img/5D.png
## 2 https://deckofcardsapi.com/static/img/6D.png
##
## $remaining
## [1] 50
knitr::include_graphics(cards$cards$images.svg)
In this section, we are going to show you how we use an API which requires an API key. API key allows you to use the services the API provides on behalf of yourself.
r <- GET(
"https://api.geodatasource.com/cities",
query = list(
key = "YOUR PRIVATE API KEY",
lat = 38.5449,
lng = -121.741
)
)
# check if the status is ok
stop_for_status(r)
json <- content(r, as = "text")
fromJSON(json)
There are multiple ways to protect your API key.
.Renviron
. In the file .Renviron
, putGEODATA_KEY="YOUR API KEY"
You could put this file in various places.
Project home directory
usethis::edit_r_environ("project")
The file .Renviron
is loaded automatically every time when R restarts.
Under the same directory as the Rscript
.Renviron
in the same directory as your script and put your API key into it.readRenviron(".Renviron")
# you might need to change your working directory and restart R session to make it work
r <- GET(
"https://api.geodatasource.com/cities",
query = list(
key = Sys.getenv("GEODATA_KEY"),
lat = 38.5449,
lng = -121.741
)
)
stop_for_status(r)
fromJSON(content(r, as = "text"))
## country region city latitude longitude
## 1 US California Davis 38.5449 -121.741
## 2 US California Davis Mobile Estates 38.5422 -121.738
## 3 US California Royal Oak Manufactured Home Community 38.5447 -121.73
## 4 US California Briggston 38.5313 -121.749
## 5 US California Rancho Yolo Mobile Home Park 38.5522 -121.724
## 6 US California El Macero 38.5468 -121.694
## 7 US California Swingle 38.5582 -121.676
## 8 US California Plainfield 38.5907 -121.797
## 9 US California Webster 38.5621 -121.655
## 10 US California Merritt 38.6141 -121.761
## 11 US California Sucro 38.4696 -121.805
## 12 US California Saxon 38.4666 -121.656
## 13 US California Dixon 38.4455 -121.823
## currency_code currency_name currency_symbol sunrise sunset time_zone
## 1 USD United States Dollar $ 06:43 17:56 -08:00
## 2 USD United States Dollar $ 06:43 17:56 -08:00
## 3 USD United States Dollar $ 06:43 17:56 -08:00
## 4 USD United States Dollar $ 06:43 17:56 -08:00
## 5 USD United States Dollar $ 06:43 17:56 -08:00
## 6 USD United States Dollar $ 06:43 17:55 -08:00
## 7 USD United States Dollar $ 06:43 17:55 -08:00
## 8 USD United States Dollar $ 06:43 17:56 -08:00
## 9 USD United States Dollar $ 06:43 17:55 -08:00
## 10 USD United States Dollar $ 06:43 17:56 -08:00
## 11 USD United States Dollar $ 06:43 17:56 -08:00
## 12 USD United States Dollar $ 06:43 17:55 -08:00
## 13 USD United States Dollar $ 06:43 17:56 -08:00
## distance_km
## 1 0.0003
## 2 0.3980
## 3 0.9566
## 4 1.6647
## 5 1.6867
## 6 4.0929
## 7 5.8425
## 8 7.0452
## 9 7.7191
## 10 7.8888
## 11 10.0557
## 12 11.4243
## 13 13.1563
keyring
. (PS: this method doesn’t work for shiny app)# to set a secret, use
# only need to do it once, you will be prompted for the API key
# the password is stored in your system password manager
keyring::key_set("GEODATA_KEY")
r <- GET(
"https://api.geodatasource.com/cities",
query = list(
key = keyring::key_get("GEODATA_KEY"),
lat = 38.5449,
lng = -121.741
)
)
stop_for_status(r)
json <- content(r, as = "text")
fromJSON(json)
keyring::key_delete("GEODATA_KEY")
r <- GET(
"https://content.guardianapis.com/search",
query = list(
`api-key` = Sys.getenv("GUARDIAN_KEY"),
q = 'coronavirus',
`page-size` = 10
)
)
stop_for_status(r)
result <- fromJSON(content(r, as = "text", encoding = "UTF-8"))
result$response$results
## id
## 1 artanddesign/2020/dec/21/inside-oxfords-coronavirus-vaccine-development
## 2 world/2021/jan/29/catastrophic-errors-in-the-handling-of-coronavirus
## 3 world/2021/jan/07/us-suffers-record-daily-coronavirus-deaths
## 4 uk-news/2021/feb/23/scotlands-stages-how-coronavirus-lockdown-will-be-eased
## 5 world/2021/feb/24/covid-uk-coronavirus-cases-deaths-and-vaccinations-today
## 6 australia-news/2021/feb/16/astrazeneca-coronavirus-vaccine-approved-by-australias-drug-regulator
## 7 football/2021/jan/15/crystal-palace-play-it-safe-on-coronavirus
## 8 world/2020/dec/01/uk-coronavirus-death-toll-passes-75000
## 9 us-news/2020/dec/29/coronavirus-sharpens-economic-inequalities-america
## 10 world/2021/feb/03/israel-opens-coronavirus-vaccines-to-all-over-16s
## type sectionId sectionName webPublicationDate
## 1 article artanddesign Art and design 2020-12-21T07:00:40Z
## 2 article world World news 2021-01-29T17:57:19Z
## 3 article world World news 2021-01-07T06:38:06Z
## 4 article uk-news UK news 2021-02-23T18:09:24Z
## 5 article world World news 2021-02-24T09:54:37Z
## 6 article australia-news Australia news 2021-02-16T03:46:48Z
## 7 article football Football 2021-01-15T18:21:23Z
## 8 article world World news 2020-12-01T17:01:59Z
## 9 article us-news US news 2020-12-29T11:00:40Z
## 10 article world World news 2021-02-03T13:05:40Z
## webTitle
## 1 Inside Oxford’s coronavirus vaccine development
## 2 Catastrophic errors in the handling of coronavirus | Letters
## 3 US suffers record daily coronavirus deaths
## 4 Scotland's stages: how coronavirus lockdown will be eased
## 5 Covid: UK Coronavirus cases, deaths and vaccinations today
## 6 AstraZeneca coronavirus vaccine approved by Australia's drug regulator
## 7 Crystal Palace play it safe on coronavirus | Brief letters
## 8 UK coronavirus death toll passes 75,000
## 9 Coronavirus sharpens America's already stark economic inequalities
## 10 Israel opens coronavirus vaccines to all over-16s
## webUrl
## 1 https://www.theguardian.com/artanddesign/2020/dec/21/inside-oxfords-coronavirus-vaccine-development
## 2 https://www.theguardian.com/world/2021/jan/29/catastrophic-errors-in-the-handling-of-coronavirus
## 3 https://www.theguardian.com/world/2021/jan/07/us-suffers-record-daily-coronavirus-deaths
## 4 https://www.theguardian.com/uk-news/2021/feb/23/scotlands-stages-how-coronavirus-lockdown-will-be-eased
## 5 https://www.theguardian.com/world/2021/feb/24/covid-uk-coronavirus-cases-deaths-and-vaccinations-today
## 6 https://www.theguardian.com/australia-news/2021/feb/16/astrazeneca-coronavirus-vaccine-approved-by-australias-drug-regulator
## 7 https://www.theguardian.com/football/2021/jan/15/crystal-palace-play-it-safe-on-coronavirus
## 8 https://www.theguardian.com/world/2020/dec/01/uk-coronavirus-death-toll-passes-75000
## 9 https://www.theguardian.com/us-news/2020/dec/29/coronavirus-sharpens-economic-inequalities-america
## 10 https://www.theguardian.com/world/2021/feb/03/israel-opens-coronavirus-vaccines-to-all-over-16s
## apiUrl
## 1 https://content.guardianapis.com/artanddesign/2020/dec/21/inside-oxfords-coronavirus-vaccine-development
## 2 https://content.guardianapis.com/world/2021/jan/29/catastrophic-errors-in-the-handling-of-coronavirus
## 3 https://content.guardianapis.com/world/2021/jan/07/us-suffers-record-daily-coronavirus-deaths
## 4 https://content.guardianapis.com/uk-news/2021/feb/23/scotlands-stages-how-coronavirus-lockdown-will-be-eased
## 5 https://content.guardianapis.com/world/2021/feb/24/covid-uk-coronavirus-cases-deaths-and-vaccinations-today
## 6 https://content.guardianapis.com/australia-news/2021/feb/16/astrazeneca-coronavirus-vaccine-approved-by-australias-drug-regulator
## 7 https://content.guardianapis.com/football/2021/jan/15/crystal-palace-play-it-safe-on-coronavirus
## 8 https://content.guardianapis.com/world/2020/dec/01/uk-coronavirus-death-toll-passes-75000
## 9 https://content.guardianapis.com/us-news/2020/dec/29/coronavirus-sharpens-economic-inequalities-america
## 10 https://content.guardianapis.com/world/2021/feb/03/israel-opens-coronavirus-vaccines-to-all-over-16s
## isHosted pillarId pillarName
## 1 FALSE pillar/arts Arts
## 2 FALSE pillar/news News
## 3 FALSE pillar/news News
## 4 FALSE pillar/news News
## 5 FALSE pillar/news News
## 6 FALSE pillar/news News
## 7 FALSE pillar/sport Sport
## 8 FALSE pillar/news News
## 9 FALSE pillar/news News
## 10 FALSE pillar/news News
Only 10 results?
result$response$pages
## [1] 3132
There are many more pages! How to get the second page?
r <- GET(
"https://content.guardianapis.com/search",
query = list(
`api-key` = Sys.getenv("GUARDIAN_KEY"),
q = "coronavirus",
`page-size` = 10,
page = 2
)
)
stop_for_status(r)
json <- content(r, as = "text", encoding = "UTF-8")
result <- fromJSON(json)
result$response$results
## id
## 1 world/2020/nov/25/smarter-ways-tips-navigate-christmas-coronavirus-uk
## 2 us-news/2020/dec/29/coronavirus-sharpens-economic-inequalities-america
## 3 society/2020/dec/02/beware-fake-coronavirus-vaccines-says-interpol
## 4 australia-news/2021/feb/17/coronavirus-victoria-covid-melbourne-lockdown-restrictions-rules-covid19-explained-mask-exercising-what-you-need-to-know
## 5 lifeandstyle/2021/feb/09/share-your-experiences-of-dating-during-the-coronavirus-pandemic
## 6 world/2020/nov/18/us-passes-250000-deaths-from-coronavirus
## 7 world/2021/jan/08/california-hospitals-coronavirus-cases-deaths
## 8 world/2021/jan/15/global-coronavirus-death-toll-reaches-2-million-people
## 9 world/2021/jan/31/captain-sir-tom-moore-tests-positive-for-covid-19-and-is-in-hospital
## 10 world/ng-interactive/2020/dec/16/covid-chaos-a-timeline-of-the-uks-handling-of-the-coronavirus-crisis
## type sectionId sectionName webPublicationDate
## 1 article world World news 2020-11-25T18:49:56Z
## 2 article us-news US news 2020-12-29T11:00:40Z
## 3 article society Society 2020-12-02T11:25:26Z
## 4 article australia-news Australia news 2021-02-17T01:36:28Z
## 5 article lifeandstyle Life and style 2021-02-09T11:37:01Z
## 6 article world World news 2020-11-18T22:49:04Z
## 7 article world World news 2021-01-08T20:54:12Z
## 8 article world World news 2021-01-16T05:21:24Z
## 9 article world World news 2021-01-31T17:31:48Z
## 10 interactive world World news 2021-02-03T15:48:25Z
## webTitle
## 1 Coronavirus: tips for a safer Christmas
## 2 Coronavirus sharpens America's already stark economic inequalities
## 3 Beware fake coronavirus vaccines, says Interpol
## 4 Coronavirus Victoria: Covid lockdown rules and Vic restrictions explained
## 5 Share your experiences of dating during the coronavirus pandemic
## 6 US passes 250,000 deaths from coronavirus
## 7 California struggles under a staggering 2.5m coronavirus cases
## 8 Global report: coronavirus death toll reaches 2 million
## 9 Captain Sir Tom Moore admitted to hospital with coronavirus
## 10 Covid chaos: how the UK handled the coronavirus crisis
## webUrl
## 1 https://www.theguardian.com/world/2020/nov/25/smarter-ways-tips-navigate-christmas-coronavirus-uk
## 2 https://www.theguardian.com/us-news/2020/dec/29/coronavirus-sharpens-economic-inequalities-america
## 3 https://www.theguardian.com/society/2020/dec/02/beware-fake-coronavirus-vaccines-says-interpol
## 4 https://www.theguardian.com/australia-news/2021/feb/17/coronavirus-victoria-covid-melbourne-lockdown-restrictions-rules-covid19-explained-mask-exercising-what-you-need-to-know
## 5 https://www.theguardian.com/lifeandstyle/2021/feb/09/share-your-experiences-of-dating-during-the-coronavirus-pandemic
## 6 https://www.theguardian.com/world/2020/nov/18/us-passes-250000-deaths-from-coronavirus
## 7 https://www.theguardian.com/world/2021/jan/08/california-hospitals-coronavirus-cases-deaths
## 8 https://www.theguardian.com/world/2021/jan/15/global-coronavirus-death-toll-reaches-2-million-people
## 9 https://www.theguardian.com/world/2021/jan/31/captain-sir-tom-moore-tests-positive-for-covid-19-and-is-in-hospital
## 10 https://www.theguardian.com/world/ng-interactive/2020/dec/16/covid-chaos-a-timeline-of-the-uks-handling-of-the-coronavirus-crisis
## apiUrl
## 1 https://content.guardianapis.com/world/2020/nov/25/smarter-ways-tips-navigate-christmas-coronavirus-uk
## 2 https://content.guardianapis.com/us-news/2020/dec/29/coronavirus-sharpens-economic-inequalities-america
## 3 https://content.guardianapis.com/society/2020/dec/02/beware-fake-coronavirus-vaccines-says-interpol
## 4 https://content.guardianapis.com/australia-news/2021/feb/17/coronavirus-victoria-covid-melbourne-lockdown-restrictions-rules-covid19-explained-mask-exercising-what-you-need-to-know
## 5 https://content.guardianapis.com/lifeandstyle/2021/feb/09/share-your-experiences-of-dating-during-the-coronavirus-pandemic
## 6 https://content.guardianapis.com/world/2020/nov/18/us-passes-250000-deaths-from-coronavirus
## 7 https://content.guardianapis.com/world/2021/jan/08/california-hospitals-coronavirus-cases-deaths
## 8 https://content.guardianapis.com/world/2021/jan/15/global-coronavirus-death-toll-reaches-2-million-people
## 9 https://content.guardianapis.com/world/2021/jan/31/captain-sir-tom-moore-tests-positive-for-covid-19-and-is-in-hospital
## 10 https://content.guardianapis.com/world/ng-interactive/2020/dec/16/covid-chaos-a-timeline-of-the-uks-handling-of-the-coronavirus-crisis
## isHosted pillarId pillarName
## 1 FALSE pillar/news News
## 2 FALSE pillar/news News
## 3 FALSE pillar/news News
## 4 FALSE pillar/news News
## 5 FALSE pillar/lifestyle Lifestyle
## 6 FALSE pillar/news News
## 7 FALSE pillar/news News
## 8 FALSE pillar/news News
## 9 FALSE pillar/news News
## 10 FALSE pillar/news News
r <- GET(
"https://api.wolframalpha.com/v2/query",
query = list(
appid = Sys.getenv("WOLFRAM_ALPHA_KEY"),
input = "integrate x^3",
format = "plaintext",
output = "json"
)
)
stop_for_status(r)
json <- content(r, as = "text", encoding = "UTF-8")
fromJSON(json, flatten = TRUE)$queryresult$pods %>%
hoist(subpods, text = "plaintext") %>%
select(title, text) %>%
unnest(text)
## # A tibble: 2 x 2
## title text
## <chr> <chr>
## 1 Indefinite integral "integral x^3 dx = x^4/4 + constant"
## 2 Plot of the integral ""
You will need to register a google clould platfram account with $300 credit first. THen following the instruction here to generate an api key. https://developers.google.com/places/web-service/get-api-key
r <- GET(
"https://maps.googleapis.com/maps/api/place/nearbysearch/json",
query = list(
key = Sys.getenv("GOOGLE_API_KEY"),
location = "38.5449,-121.741",
radius = 500,
types = "food",
name = "in-n-out"
)
)
stop_for_status(r)
json <- content(r, as = "text", encoding = "UTF-8")
fromJSON(json, flatten = TRUE)$results %>% pull(vicinity)
## [1] "1020 Olive Dr, Davis"
GitHub requires API token instead of an API key.
r <- GET(
str_glue("https://api.github.com/users/{username}/repos", username = "randy3k"),
add_headers(Authorization = paste("token", Sys.getenv("GITHUB_PAT")))
)
stop_for_status(r)
json <- content(r, as = "text")
fromJSON(json)
## id node_id name full_name private
## 1 222521499 MDEwOlJlcG9zaXRvcnkyMjI1MjE0OTk= actions randy3k/actions FALSE
## 2 7086462 MDEwOlJlcG9zaXRvcnk3MDg2NDYy AlignTab randy3k/AlignTab FALSE
## owner.login owner.id owner.node_id
## 1 randy3k 1690993 MDQ6VXNlcjE2OTA5OTM=
## 2 randy3k 1690993 MDQ6VXNlcjE2OTA5OTM=
## owner.avatar_url owner.gravatar_id
## 1 https://avatars.githubusercontent.com/u/1690993?v=4
## 2 https://avatars.githubusercontent.com/u/1690993?v=4
## owner.url owner.html_url
## 1 https://api.github.com/users/randy3k https://github.com/randy3k
## 2 https://api.github.com/users/randy3k https://github.com/randy3k
## owner.followers_url
## 1 https://api.github.com/users/randy3k/followers
## 2 https://api.github.com/users/randy3k/followers
## owner.following_url
## 1 https://api.github.com/users/randy3k/following{/other_user}
## 2 https://api.github.com/users/randy3k/following{/other_user}
## owner.gists_url
## 1 https://api.github.com/users/randy3k/gists{/gist_id}
## 2 https://api.github.com/users/randy3k/gists{/gist_id}
## owner.starred_url
## 1 https://api.github.com/users/randy3k/starred{/owner}{/repo}
## 2 https://api.github.com/users/randy3k/starred{/owner}{/repo}
## owner.subscriptions_url
## 1 https://api.github.com/users/randy3k/subscriptions
## 2 https://api.github.com/users/randy3k/subscriptions
## owner.organizations_url
## 1 https://api.github.com/users/randy3k/orgs
## 2 https://api.github.com/users/randy3k/orgs
## owner.repos_url
## 1 https://api.github.com/users/randy3k/repos
## 2 https://api.github.com/users/randy3k/repos
## owner.events_url
## 1 https://api.github.com/users/randy3k/events{/privacy}
## 2 https://api.github.com/users/randy3k/events{/privacy}
## owner.received_events_url owner.type
## 1 https://api.github.com/users/randy3k/received_events User
## 2 https://api.github.com/users/randy3k/received_events User
## owner.site_admin html_url
## 1 FALSE https://github.com/randy3k/actions
## 2 FALSE https://github.com/randy3k/AlignTab
## description fork
## 1 GitHub Actions for the R community TRUE
## 2 An alignment plugin for Sublime Text using regular expression FALSE
## url
## 1 https://api.github.com/repos/randy3k/actions
## 2 https://api.github.com/repos/randy3k/AlignTab
## forks_url
## 1 https://api.github.com/repos/randy3k/actions/forks
## 2 https://api.github.com/repos/randy3k/AlignTab/forks
## keys_url
## 1 https://api.github.com/repos/randy3k/actions/keys{/key_id}
## 2 https://api.github.com/repos/randy3k/AlignTab/keys{/key_id}
## collaborators_url
## 1 https://api.github.com/repos/randy3k/actions/collaborators{/collaborator}
## 2 https://api.github.com/repos/randy3k/AlignTab/collaborators{/collaborator}
## teams_url
## 1 https://api.github.com/repos/randy3k/actions/teams
## 2 https://api.github.com/repos/randy3k/AlignTab/teams
## hooks_url
## 1 https://api.github.com/repos/randy3k/actions/hooks
## 2 https://api.github.com/repos/randy3k/AlignTab/hooks
## issue_events_url
## 1 https://api.github.com/repos/randy3k/actions/issues/events{/number}
## 2 https://api.github.com/repos/randy3k/AlignTab/issues/events{/number}
## events_url
## 1 https://api.github.com/repos/randy3k/actions/events
## 2 https://api.github.com/repos/randy3k/AlignTab/events
## assignees_url
## 1 https://api.github.com/repos/randy3k/actions/assignees{/user}
## 2 https://api.github.com/repos/randy3k/AlignTab/assignees{/user}
## branches_url
## 1 https://api.github.com/repos/randy3k/actions/branches{/branch}
## 2 https://api.github.com/repos/randy3k/AlignTab/branches{/branch}
## tags_url
## 1 https://api.github.com/repos/randy3k/actions/tags
## 2 https://api.github.com/repos/randy3k/AlignTab/tags
## blobs_url
## 1 https://api.github.com/repos/randy3k/actions/git/blobs{/sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/git/blobs{/sha}
## git_tags_url
## 1 https://api.github.com/repos/randy3k/actions/git/tags{/sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/git/tags{/sha}
## git_refs_url
## 1 https://api.github.com/repos/randy3k/actions/git/refs{/sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/git/refs{/sha}
## trees_url
## 1 https://api.github.com/repos/randy3k/actions/git/trees{/sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/git/trees{/sha}
## statuses_url
## 1 https://api.github.com/repos/randy3k/actions/statuses/{sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/statuses/{sha}
## languages_url
## 1 https://api.github.com/repos/randy3k/actions/languages
## 2 https://api.github.com/repos/randy3k/AlignTab/languages
## stargazers_url
## 1 https://api.github.com/repos/randy3k/actions/stargazers
## 2 https://api.github.com/repos/randy3k/AlignTab/stargazers
## contributors_url
## 1 https://api.github.com/repos/randy3k/actions/contributors
## 2 https://api.github.com/repos/randy3k/AlignTab/contributors
## subscribers_url
## 1 https://api.github.com/repos/randy3k/actions/subscribers
## 2 https://api.github.com/repos/randy3k/AlignTab/subscribers
## subscription_url
## 1 https://api.github.com/repos/randy3k/actions/subscription
## 2 https://api.github.com/repos/randy3k/AlignTab/subscription
## commits_url
## 1 https://api.github.com/repos/randy3k/actions/commits{/sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/commits{/sha}
## git_commits_url
## 1 https://api.github.com/repos/randy3k/actions/git/commits{/sha}
## 2 https://api.github.com/repos/randy3k/AlignTab/git/commits{/sha}
## comments_url
## 1 https://api.github.com/repos/randy3k/actions/comments{/number}
## 2 https://api.github.com/repos/randy3k/AlignTab/comments{/number}
## issue_comment_url
## 1 https://api.github.com/repos/randy3k/actions/issues/comments{/number}
## 2 https://api.github.com/repos/randy3k/AlignTab/issues/comments{/number}
## contents_url
## 1 https://api.github.com/repos/randy3k/actions/contents/{+path}
## 2 https://api.github.com/repos/randy3k/AlignTab/contents/{+path}
## compare_url
## 1 https://api.github.com/repos/randy3k/actions/compare/{base}...{head}
## 2 https://api.github.com/repos/randy3k/AlignTab/compare/{base}...{head}
## merges_url
## 1 https://api.github.com/repos/randy3k/actions/merges
## 2 https://api.github.com/repos/randy3k/AlignTab/merges
## archive_url
## 1 https://api.github.com/repos/randy3k/actions/{archive_format}{/ref}
## 2 https://api.github.com/repos/randy3k/AlignTab/{archive_format}{/ref}
## downloads_url
## 1 https://api.github.com/repos/randy3k/actions/downloads
## 2 https://api.github.com/repos/randy3k/AlignTab/downloads
## issues_url
## 1 https://api.github.com/repos/randy3k/actions/issues{/number}
## 2 https://api.github.com/repos/randy3k/AlignTab/issues{/number}
## pulls_url
## 1 https://api.github.com/repos/randy3k/actions/pulls{/number}
## 2 https://api.github.com/repos/randy3k/AlignTab/pulls{/number}
## milestones_url
## 1 https://api.github.com/repos/randy3k/actions/milestones{/number}
## 2 https://api.github.com/repos/randy3k/AlignTab/milestones{/number}
## notifications_url
## 1 https://api.github.com/repos/randy3k/actions/notifications{?since,all,participating}
## 2 https://api.github.com/repos/randy3k/AlignTab/notifications{?since,all,participating}
## labels_url
## 1 https://api.github.com/repos/randy3k/actions/labels{/name}
## 2 https://api.github.com/repos/randy3k/AlignTab/labels{/name}
## releases_url
## 1 https://api.github.com/repos/randy3k/actions/releases{/id}
## 2 https://api.github.com/repos/randy3k/AlignTab/releases{/id}
## deployments_url
## 1 https://api.github.com/repos/randy3k/actions/deployments
## 2 https://api.github.com/repos/randy3k/AlignTab/deployments
## created_at updated_at pushed_at
## 1 2019-11-18T18:56:00Z 2020-02-06T02:36:25Z 2020-05-25T18:00:31Z
## 2 2012-12-10T02:25:22Z 2021-02-17T11:44:21Z 2020-10-15T18:18:34Z
## git_url ssh_url
## 1 git://github.com/randy3k/actions.git git@github.com:randy3k/actions.git
## 2 git://github.com/randy3k/AlignTab.git git@github.com:randy3k/AlignTab.git
## clone_url svn_url
## 1 https://github.com/randy3k/actions.git https://github.com/randy3k/actions
## 2 https://github.com/randy3k/AlignTab.git https://github.com/randy3k/AlignTab
## homepage size stargazers_count watchers_count language has_issues
## 1 777 0 0 JavaScript FALSE
## 2 1462 610 610 Python TRUE
## has_projects has_downloads has_wiki has_pages forks_count mirror_url archived
## 1 TRUE TRUE TRUE FALSE 0 NA FALSE
## 2 TRUE TRUE TRUE FALSE 27 NA FALSE
## disabled open_issues_count license.key license.name
## 1 FALSE 0 cc0-1.0 Creative Commons Zero v1.0 Universal
## 2 FALSE 16 mit MIT License
## license.spdx_id license.url license.node_id
## 1 CC0-1.0 https://api.github.com/licenses/cc0-1.0 MDc6TGljZW5zZTY=
## 2 MIT https://api.github.com/licenses/mit MDc6TGljZW5zZTEz
## forks open_issues watchers default_branch permissions.admin permissions.push
## 1 0 0 0 master TRUE TRUE
## 2 27 16 610 master TRUE TRUE
## permissions.pull
## 1 TRUE
## 2 TRUE
## [ reached 'max' / getOption("max.print") -- omitted 28 rows ]
Only 30 repos? How to go to next page?
r$headers$link
## [1] "<https://api.github.com/user/1690993/repos?page=2>; rel=\"next\", <https://api.github.com/user/1690993/repos?page=5>; rel=\"last\""
r2 <- GET("https://api.github.com/user/1690993/repos?page=2",
add_headers(Authorization = paste("token", Sys.getenv("GITHUB_PAT"))))
stop_for_status(r2)
json <- content(r2, as = "text")
fromJSON(json)
## id node_id name
## 1 60392032 MDEwOlJlcG9zaXRvcnk2MDM5MjAzMg== homebrew-r
## 2 115029972 MDEwOlJlcG9zaXRvcnkxMTUwMjk5NzI= homebrew-science
## full_name private owner.login owner.id owner.node_id
## 1 randy3k/homebrew-r FALSE randy3k 1690993 MDQ6VXNlcjE2OTA5OTM=
## 2 randy3k/homebrew-science FALSE randy3k 1690993 MDQ6VXNlcjE2OTA5OTM=
## owner.avatar_url owner.gravatar_id
## 1 https://avatars.githubusercontent.com/u/1690993?v=4
## 2 https://avatars.githubusercontent.com/u/1690993?v=4
## owner.url owner.html_url
## 1 https://api.github.com/users/randy3k https://github.com/randy3k
## 2 https://api.github.com/users/randy3k https://github.com/randy3k
## owner.followers_url
## 1 https://api.github.com/users/randy3k/followers
## 2 https://api.github.com/users/randy3k/followers
## owner.following_url
## 1 https://api.github.com/users/randy3k/following{/other_user}
## 2 https://api.github.com/users/randy3k/following{/other_user}
## owner.gists_url
## 1 https://api.github.com/users/randy3k/gists{/gist_id}
## 2 https://api.github.com/users/randy3k/gists{/gist_id}
## owner.starred_url
## 1 https://api.github.com/users/randy3k/starred{/owner}{/repo}
## 2 https://api.github.com/users/randy3k/starred{/owner}{/repo}
## owner.subscriptions_url
## 1 https://api.github.com/users/randy3k/subscriptions
## 2 https://api.github.com/users/randy3k/subscriptions
## owner.organizations_url
## 1 https://api.github.com/users/randy3k/orgs
## 2 https://api.github.com/users/randy3k/orgs
## owner.repos_url
## 1 https://api.github.com/users/randy3k/repos
## 2 https://api.github.com/users/randy3k/repos
## owner.events_url
## 1 https://api.github.com/users/randy3k/events{/privacy}
## 2 https://api.github.com/users/randy3k/events{/privacy}
## owner.received_events_url owner.type
## 1 https://api.github.com/users/randy3k/received_events User
## 2 https://api.github.com/users/randy3k/received_events User
## owner.site_admin html_url
## 1 FALSE https://github.com/randy3k/homebrew-r
## 2 FALSE https://github.com/randy3k/homebrew-science
## description fork
## 1 Homebrew formulas for R and related tools FALSE
## 2 :beer::microscope: Scientific formulae for the Homebrew package manager TRUE
## url
## 1 https://api.github.com/repos/randy3k/homebrew-r
## 2 https://api.github.com/repos/randy3k/homebrew-science
## forks_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/forks
## 2 https://api.github.com/repos/randy3k/homebrew-science/forks
## keys_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/keys{/key_id}
## 2 https://api.github.com/repos/randy3k/homebrew-science/keys{/key_id}
## collaborators_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/collaborators{/collaborator}
## 2 https://api.github.com/repos/randy3k/homebrew-science/collaborators{/collaborator}
## teams_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/teams
## 2 https://api.github.com/repos/randy3k/homebrew-science/teams
## hooks_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/hooks
## 2 https://api.github.com/repos/randy3k/homebrew-science/hooks
## issue_events_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/issues/events{/number}
## 2 https://api.github.com/repos/randy3k/homebrew-science/issues/events{/number}
## events_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/events
## 2 https://api.github.com/repos/randy3k/homebrew-science/events
## assignees_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/assignees{/user}
## 2 https://api.github.com/repos/randy3k/homebrew-science/assignees{/user}
## branches_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/branches{/branch}
## 2 https://api.github.com/repos/randy3k/homebrew-science/branches{/branch}
## tags_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/tags
## 2 https://api.github.com/repos/randy3k/homebrew-science/tags
## blobs_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/git/blobs{/sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/git/blobs{/sha}
## git_tags_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/git/tags{/sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/git/tags{/sha}
## git_refs_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/git/refs{/sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/git/refs{/sha}
## trees_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/git/trees{/sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/git/trees{/sha}
## statuses_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/statuses/{sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/statuses/{sha}
## languages_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/languages
## 2 https://api.github.com/repos/randy3k/homebrew-science/languages
## stargazers_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/stargazers
## 2 https://api.github.com/repos/randy3k/homebrew-science/stargazers
## contributors_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/contributors
## 2 https://api.github.com/repos/randy3k/homebrew-science/contributors
## subscribers_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/subscribers
## 2 https://api.github.com/repos/randy3k/homebrew-science/subscribers
## subscription_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/subscription
## 2 https://api.github.com/repos/randy3k/homebrew-science/subscription
## commits_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/commits{/sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/commits{/sha}
## git_commits_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/git/commits{/sha}
## 2 https://api.github.com/repos/randy3k/homebrew-science/git/commits{/sha}
## comments_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/comments{/number}
## 2 https://api.github.com/repos/randy3k/homebrew-science/comments{/number}
## issue_comment_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/issues/comments{/number}
## 2 https://api.github.com/repos/randy3k/homebrew-science/issues/comments{/number}
## contents_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/contents/{+path}
## 2 https://api.github.com/repos/randy3k/homebrew-science/contents/{+path}
## compare_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/compare/{base}...{head}
## 2 https://api.github.com/repos/randy3k/homebrew-science/compare/{base}...{head}
## merges_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/merges
## 2 https://api.github.com/repos/randy3k/homebrew-science/merges
## archive_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/{archive_format}{/ref}
## 2 https://api.github.com/repos/randy3k/homebrew-science/{archive_format}{/ref}
## downloads_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/downloads
## 2 https://api.github.com/repos/randy3k/homebrew-science/downloads
## issues_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/issues{/number}
## 2 https://api.github.com/repos/randy3k/homebrew-science/issues{/number}
## pulls_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/pulls{/number}
## 2 https://api.github.com/repos/randy3k/homebrew-science/pulls{/number}
## milestones_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/milestones{/number}
## 2 https://api.github.com/repos/randy3k/homebrew-science/milestones{/number}
## notifications_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/notifications{?since,all,participating}
## 2 https://api.github.com/repos/randy3k/homebrew-science/notifications{?since,all,participating}
## labels_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/labels{/name}
## 2 https://api.github.com/repos/randy3k/homebrew-science/labels{/name}
## releases_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/releases{/id}
## 2 https://api.github.com/repos/randy3k/homebrew-science/releases{/id}
## deployments_url
## 1 https://api.github.com/repos/randy3k/homebrew-r/deployments
## 2 https://api.github.com/repos/randy3k/homebrew-science/deployments
## created_at updated_at pushed_at
## 1 2016-06-04T03:50:10Z 2021-02-24T21:43:21Z 2020-12-31T23:33:52Z
## 2 2017-12-21T17:20:18Z 2017-12-21T17:20:22Z 2017-12-21T17:56:51Z
## git_url
## 1 git://github.com/randy3k/homebrew-r.git
## 2 git://github.com/randy3k/homebrew-science.git
## ssh_url
## 1 git@github.com:randy3k/homebrew-r.git
## 2 git@github.com:randy3k/homebrew-science.git
## clone_url
## 1 https://github.com/randy3k/homebrew-r.git
## 2 https://github.com/randy3k/homebrew-science.git
## svn_url
## 1 https://github.com/randy3k/homebrew-r
## 2 https://github.com/randy3k/homebrew-science
## homepage size
## 1 145
## 2 http://formulae.brew.sh/repos/Homebrew/homebrew-science/browse/a 9976
## stargazers_count watchers_count language has_issues has_projects
## 1 25 25 Ruby TRUE TRUE
## 2 0 0 Ruby FALSE TRUE
## has_downloads has_wiki has_pages forks_count mirror_url archived disabled
## 1 TRUE TRUE FALSE 7 NA FALSE FALSE
## 2 TRUE TRUE FALSE 0 NA FALSE FALSE
## open_issues_count license.key license.name license.spdx_id license.url
## 1 1 <NA> <NA> <NA> <NA>
## 2 0 other Other NOASSERTION <NA>
## license.node_id forks open_issues watchers default_branch permissions.admin
## 1 <NA> 7 1 25 master TRUE
## 2 MDc6TGljZW5zZTA= 0 0 0 master TRUE
## permissions.push permissions.pull
## 1 TRUE TRUE
## 2 TRUE TRUE
## [ reached 'max' / getOption("max.print") -- omitted 28 rows ]
r2$headers$link
## [1] "<https://api.github.com/user/1690993/repos?page=1>; rel=\"prev\", <https://api.github.com/user/1690993/repos?page=3>; rel=\"next\", <https://api.github.com/user/1690993/repos?page=5>; rel=\"last\", <https://api.github.com/user/1690993/repos?page=1>; rel=\"first\""
Yelp requires Bearer token directory instead of an API key.
First, you will need to register an app on yelp: https://www.yelp.com/developers
r <- GET(
"https://api.yelp.com/v3/businesses/search",
add_headers(Authorization = paste("Bearer", Sys.getenv("YELP_TOKEN"))),
query = list(
location = "Davis"
)
)
stop_for_status(r)
json <- content(r, as = "text")
## No encoding supplied: defaulting to UTF-8.
fromJSON(json, flatten = TRUE)$businesses %>% select(name)
## name
## 1 Sam's Mediterranean Cuisine
## 2 Burgers and Brew
## 3 Dutch Bros Coffee
## 4 Four Seasons Gourmet Chinese Restaurant
## 5 Taqueria Davis
## 6 Nugget Markets
## 7 Zumapoke & Lush Ice
## 8 Mikuni Japanese Restaurant and Sushi Bar
## 9 Sweet and Shavery
## 10 Taqueria Guadalajara
## 11 Woodstock's Pizza Davis
## 12 Temple Coffee Roasters
## 13 Crepeville
## 14 Blaze Pizza
## 15 Thai Canteen
## 16 Tommy J's Grill & Catering
## 17 Raja's Tandoor
## 18 Tea List
## 19 Fish's Wild Island Grill
## 20 In-N-Out Burger
OAuth is a technique to allow developers to access the API on behalf on themselves or other users.
There are two versions of OAuth, 1.0 and 2.0. You should not think that 2.0 is better than 1.0. They are simply different implementations.
OAuth is complex but fun to learn about. Read this https://oauth.net/2/ if you are interested.
In OAuth protocol, there are two important pieces of strings
To put is simple, there are three cases - one legged OAuth: developer directly use the key and secret to access the API - two legged OAuth (aka: client credential flow in OAuth 2.0): developer use the key and secret to obtain an access token, and the access token will allow the developer to access the API on behalf of themself - three legged OAuth (aka: authorization code flow in OAuth 2.0): it is usually used to access the API on behalf of another user.
(Imagine that Bob is writing an email app so that Alice could read her own emails on the app.) The process is roughly the followings
library(httr)
The Noun Project uses one-legged OAuth protocol to authenticate users.
noun_app <- oauth_app(
"nounproject",
key = "ed652bdcd50a4496bbc2253a603b9e9b",
secret = Sys.getenv("NOUN_SECRET")
)
endpoint <- str_glue(
"https://api.thenounproject.com/icons/{term}",
term = "statistics")
signature <- oauth_signature(endpoint, app = noun_app)
r <- GET(endpoint, oauth_header(signature))
stop_for_status(r)
json <- content(r, as = "text", encoding = "UTF-8")
icons <- fromJSON(json)$icons %>% pull(preview_url)
knitr::include_graphics(icons[1:10])
First, create an app at https://developer.twitter.com/. You will need to register a twitter developer account first.
Twitter allows an app to access information publicly available on Twitter via two legged OAuth protocol.
twitter_app <- oauth_app("twitter",
key = "1vqbnsftUcNLucoVxQiWYnD2d",
secret = Sys.getenv("TWITTER_SECRET")
)
twitter_token <- oauth2.0_token(
oauth_endpoint(
authorize = NULL,
access = "https://api.twitter.com/oauth2/token"
),
twitter_app,
client_credentials = TRUE
)
# Where On Earth IDentifier
get_woeid <- function(city, country) {
r <- GET(
"https://api.twitter.com/1.1/trends/available.json",
config(token = twitter_token)
)
stop_for_status(r)
json <- content(r, as = "text")
fromJSON(json) %>%
filter(name == !!city , country == !!country ) %>%
pull(woeid)
}
get_trends <- function(woeid) {
r <- GET(
"https://api.twitter.com/1.1/trends/place.json",
config(token = twitter_token),
query = list(id = woeid)
)
stop_for_status(r)
json <- content(r, as = "text")
fromJSON(json)$trends[[1]]
}
woeid <- get_woeid("Sacramento", "United States")
get_trends(woeid) %>% arrange(tweet_volume) %>% select(name)
## name
## 1 LaMelo
## 2 Pacers
## 3 Skully
## 4 Ducks
## 5 Halle
## 6 Juergen Teller
## 7 Arkansas
## 8 Paige
## 9 Hawks
## 10 #EqualityAct
## 11 Rugrats
## 12 Teresa
## 13 Glenn
## 14 Blade
## 15 Suns
## 16 Soda
## 17 KCON
## 18 Miller
## 19 F-35
## 20 jype
## 21 Celtics
## 22 Franklin
## 23 Jazz
## 24 Nickelodeon
## 25 LGBTQ
## 26 #SnowfallFX
## 27 Marjorie Taylor Greene
## 28 Lakers
## 29 seulgi
## 30 Saint
## 31 Trans
## 32 #lakings
## 33 Brian Williams
## 34 Eakins
## 35 #FlyTogether
## 36 Yelich
## 37 Zegras
## 38 Marge
## 39 hader
## 40 Mike Conley
## 41 CBS All Access
## 42 #RHOSLC
## 43 Manboy
## 44 Bama
## 45 Jared dudley
## 46 Gasol
## 47 Mark Jackson
## 48 Pastor Cal
## 49 Schroder
An API key of google cannot be used to access personal data on google, we will perform a three-legged OAuth dance.
gooogle_app <- oauth_app(
"google",
key = "801676816155-un6m8s99ab1b56lida2gpd9rau9g10nj.apps.googleusercontent.com",
secret = "9fdIQ-0MVvgpFYtLdnbiEYp1" # the secret is three legged OAUTH is not really a secret
)
In OAuth, developer needs to specify that information they need from the user
google_token <- oauth2.0_token(
oauth_endpoints("google"),
gooogle_app,
scope = c(
"profile",
"email",
"https://www.googleapis.com/auth/spreadsheets"
),
cache = TRUE
)
A cache file .httr-oauth
will be created to cache the user token so the user don’t have to login everytime. However, treat it carefully, anyone could access your account with the cache.
endpoint <- str_glue(
"https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}",
spreadsheetId = "1JvqP6R44Rx96kAtEYszDezgUs2hCMp8xPvdZwUIsw-g",
range = "A:B"
)
r <- GET(endpoint, config(token = google_token))
## Auto-refreshing stale OAuth token.
stop_for_status(r)
fromJSON(content(r, as = "text"))$values
## [,1] [,2]
## [1,] "item" "price"
## [2,] "apple" "2"
## [3,] "orange" "4"
## [4,] "grape" "5"