Find APIs

️✅ Learning objectives

  • Search the web for APIs.
  • Search for API-wrapping packages.
  • Use browser developer tools to find undocumented APIs.
library(dplyr)
library(stringr)
library(tidyr)
library(tools)
library(httr2)
library(anyapi)
library(apisniffer)

Search the web for APIs

Search for API-wrapping packages

General tips for text filtering

  • tolower(FIELD) to find “API”, “api”, “Api”, etc
  • \\b in regex pattern for “word boundary”
    • "\\bapi\\b" = “api surrounded by spaces, (), newline, etc”

Searching CRAN packages

api_pkgs <- tools::CRAN_package_db() |> 
  dplyr::as_tibble() |> 
  dplyr::filter(
    stringr::str_detect(tolower(Description), "\\bapi\\b") |
      stringr::str_detect(tolower(Title), "\\bapi\\b")
  ) |> 
  dplyr::select(Package, Title)
api_pkgs
#> # A tibble: 900 × 2
#>    Package           Title                                                      
#>    <chr>             <chr>                                                      
#>  1 academictwitteR   "Access the Twitter Academic Research Product Track V2 API…
#>  2 ACEsearch         "'ACE' Search Engine API"                                  
#>  3 acled.api         "Automated Retrieval of ACLED Conflict Event Data"         
#>  4 adbcdrivermanager "'Arrow' Database Connectivity ('ADBC') Driver Manager"    
#>  5 adbcpostgresql    "'Arrow' Database Connectivity ('ADBC') 'PostgreSQL' Drive…
#>  6 adbcsqlite        "'Arrow' Database Connectivity ('ADBC') 'SQLite' Driver"   
#>  7 adformR           "Get Adform Ads Data via the 'Windsor.ai' API"             
#>  8 adobeanalyticsr   "R Client for 'Adobe Analytics' API 2.0"                   
#>  9 adsDataHubR       "Google Ads Data Hub API Client"                           
#> 10 adwordsR          "Access the 'Google Adwords' API"                          
#> # ℹ 890 more rows

Searching the R Universe

R Universe API: Request

r_universe_apis_req <- httr2::request("https://r-universe.dev/api/search") |> 
  httr2::req_url_query(
    q = "api",
    all = TRUE,
    limit = 100
  )
r_universe_apis_resps <- r_universe_apis_req |> 
  httr2::req_perform_iterative(
    httr2::iterate_with_offset(
      "skip",
      start = 0,
      offset = 100,
      resp_pages = \(resp) ceiling(httr2::resp_body_json(resp)$total/100)
    )
  )

R Universe Results

r_universe_apis_resps |> 
  httr2::resps_data(
    \(resp) {
      httr2::resp_body_json(resp)$results |> 
        tibble::enframe(name = NULL) |> 
        tidyr::unnest_wider(value)
    }
  ) |> 
  dplyr::select(Package, Title)
#> # A tibble: 1,418 × 2
#>    Package         Title                                                        
#>    <chr>           <chr>                                                        
#>  1 hoopR           "Access Men's Basketball Play by Play Data"                  
#>  2 wehoop          "Access Women's Basketball Play by Play Data"                
#>  3 gptstudio       "Use Large Language Models Directly in your Development\nEnv…
#>  4 geosapi         "GeoServer REST API R Interface"                             
#>  5 googleLanguageR "Call Google's 'Natural Language' API, 'Cloud Translation' A…
#>  6 RobinHood       "Interface for the RobinHood.com No Commission Investing Pla…
#>  7 hereR           "'sf'-Based Interface to the 'HERE' REST APIs"               
#>  8 nhlapi          "A Minimum-Dependency 'R' Interface to the 'NHL' API"        
#>  9 salesforcer     "An Implementation of 'Salesforce' APIs Using Tidy Principle…
#> 10 oaii            "'OpenAI' API R Interface"                                   
#> # ℹ 1,408 more rows

Sniff API requests in browser

Browser developer tools

  • Differs browser-to-browser, showing Chrome
  • ctrl-shift-I (cmd-shift-I) or right click > Inspect
  • Network tab
  • Filter to Fetch/XHR
  • Right click > Header Options > Path
  • Demo: Amazon suggestions

Sniff API requests with {apisniffer}

  • {apisniffer}
  • Goal:
    • Load page
    • (optional) Interact
    • Returns tibble of API info
    • (maybe) Also returns functions to access detected APIs