Kodas
install.packages(c("httr2", "jsonlite", "dplyr", "tidyr"))Internete duomenys pateikiami ne tik kaip atsisiunčiami .csv, .xlsx ar kitų formatų failai. Dalis duomenų yra pasiekiami per programų sąsajas (angl. Application Programming Interface, API). API leidžia programai automatiškai paprašyti konkrečių duomenų ir gauti juos kompiuteriui patogiu formatu.
Naudojant API nebereikia kiekvieną kartą rankiniu būdu atidaryti interneto svetainės, pasirinkti filtrų ir atsisiųsti failo. Pavyzdžiui, R programa gali pati suformuoti užklausą, ją išsiųsti, patikrinti gautą atsakymą ir paversti duomenis į vektorius, sąrašus ar duomenų lenteles.
Šiame skyriuje aptarsime:
GET užklausas ir apdoroti atsakymus naudojant R,API galima suprasti kaip iš anksto apibrėžtą taisyklių rinkinį, pagal kurį viena programa gali bendrauti su kita programa. API nurodo:
Nepainiokite API su duomenų baze! API paprasčiausiai yra sąsaja, per kurią klientui (užklausėjui) suteikiama kontroliuojama prieiga prie norimo serverio saugomų duomenų ar funkcijų.
API komunikacija paprastai vyksta tarp dviejų pusių:
R),Bendra komunikacijos eiga yra tokia:
Šį procesą galima palyginti su užsakymu restorane. Klientas pasirenka patiekalą ir pateikia užsakymą padavėjui. Padavėjas perduoda tiksliai suformuluotą užsakymą virtuvei, jį įvykdo ir grąžina rezultatą. Klientui nebūtina žinoti, kaip organizuojamas virtuvės darbas. Panašiai API naudotojui nebūtina žinoti, kaip serverio viduje saugomi ar apskaičiuojami duomenys ir kiti ištekliai.
Toliau aptarsime pagrindinius API objektus.
Išteklius (angl. resource) yra objektas arba duomenų rinkinys, su kuriuo norime atlikti veiksmą. Ištekliais gali būti įvairūs duomenys, pavyzdžiui, naudotojų sąrašas, vieno vartotojo duomenys, įvairūs ekonominiai duomenys, dokumentai ir t. t.
Kiekvienas išteklius turi adresą. API kontekste toks adresas dažnai vadinamas galiniu tašku (angl. endpoint). Pavyzdžiui, viešoje mokomojoje API naudojamas toks adresas:
https://jsonplaceholder.typicode.com/users
Šiuo adresu pasiekiamas visų naudotojų išteklius (/users). Pridėjus konkretų identifikatorių, galima kreiptis į vieno naudotojo išteklių:
https://jsonplaceholder.typicode.com/users/1
API adresą galima išskaidyti į kelias dalis:
https://jsonplaceholder.typicode.com/users/1
\______/\__________________________/\______/
schema domenas kelias
https nurodo komunikacijos protokolą,jsonplaceholder.typicode.com yra serverio domenas,/users/1 yra kelias iki konkretaus ištekliaus.Bendroji, visiems tos pačios API ištekliams pasikartojanti adreso dalis dar vadinama baziniu adresu (angl. base URL), o konkretų išteklių nusakanti dalis – galiniu tašku.
API dokumentacijose galima sutikti terminus URL (angl. Uniform Resource Locator) ir URI (angl. Uniform Resource Identifier). Praktiniuose šio skyriaus pavyzdžiuose vartosime paprastesnį terminą adresas arba URL.
Užklausa (angl. request) yra kliento siunčiamas pranešimas serveriui. Užklausoje nurodoma:
Interneto API dažniausiai naudoja HTTP protokolą. Naršyklė tuo pačiu protokolu prašo serverio pateikti interneto puslapį, o R gali juo paprašyti pateikti struktūrizuotus duomenis.
Dažnai nenorime gauti visų API turimų duomenų. Užklausos parametrais galima nurodyti filtrus, laikotarpį, rūšiavimo tvarką, puslapio numerį ar kitus pasirinkimus.
Parametrai URL adrese rašomi po klaustuko ?. Kiekvienas parametras sudaromas kaip rakto ir reikšmės pora, o kelios poros atskiriamos simboliu &. Pavyzdžiui:
https://jsonplaceholder.typicode.com/comments?postId=1
/comments;postId;1.Keliais parametrais papildytas adresas galėtų atrodyti taip:
https://api.example.com/data?year=2025®ion=LT
Tačiau kode parametrų nebūtina rankiniu būdu jungti į vieną ilgą tekstą. Vėliau aptarsime būdus, kaip juos perduoti kaip atskirą parametrų sąrašą.
HTTP metodas nurodo, kokį veiksmą klientas nori atlikti su ištekliumi. Dažniausi API metodai siejami su keturiais pagrindiniais duomenų tvarkymo veiksmais: sukurti, nuskaityti, atnaujinti ir pašalinti (angl. Create, Read, Update, Delete, CRUD).
| HTTP metodas | Veiksmas | Paskirtis |
|---|---|---|
POST |
Create | sukurti naują išteklių arba inicijuoti veiksmą |
GET |
Read | gauti išteklių ar jo atvaizdą |
PUT |
Update | visiškai pakeisti esamą išteklių |
PATCH |
Update | iš dalies pakeisti esamą išteklių |
DELETE |
Delete | pašalinti išteklių |
Kartais vartojamas platesnis trumpinys CRUDE, kur raidė E reiškia Execute – serveriui pavedama įvykdyti tam tikrą operaciją. Atskiro universalaus HTTP metodo EXECUTE nėra. Tokio veiksmo realizavimas priklauso nuo konkrečios API, o operacijai inicijuoti dažnai naudojamas POST metodas.
Labai tikėtina, kad kažkada esate susidūrę su interneto puslapio klaida “404 Not Found”. Šis kodas yra vienas iš daugelio HTTP puslapių būsenos kodų. Būsenos kodas yra triženklis skaičius. Pirmasis skaitmuo nurodo bendrą atsakymo kategoriją. Žemiau lentelėje pateiktos kodų grupės ir tam tikrų kodų pavyzdžiai.
| Kodų grupė | Reikšmė | Pavyzdžiai |
|---|---|---|
1xx |
informacinis atsakymas | užklausa priimta ir dar apdorojama |
2xx |
sėkmingas atsakymas |
200 OK, 201 Created, 204 No Content
|
3xx |
nukreipimas | išteklius pasiekiamas kitu adresu |
4xx |
kliento užklausos klaida |
400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests
|
5xx |
serverio klaida |
500 Internal Server Error, 503 Service Unavailable
|
Šiame skyriuje pagrindinį dėmesį skirsime GET, nes duomenų analizėje API dažniausiai naudojama duomenims gauti, o ne keisti serverio išteklius.
Atliekant GET užklausas dažniausiai sutinkami šie kodai:
200 OK – užklausa įvykdyta, duomenys grąžinti;400 Bad Request – netinkamai suformuota užklausa;401 Unauthorized – nepateikti arba netinkami prisijungimo duomenys;403 Forbidden – klientas neturi teisės pasiekti ištekliaus;404 Not Found – nurodytas išteklius nerastas;429 Too Many Requests – per trumpą laiką išsiųsta per daug užklausų;500 Internal Server Error – serverio vidinė klaida;503 Service Unavailable – paslauga laikinai nepasiekiama.Prieš apdorojant atsakymo turinį reikia patikrinti būsenos kodą. Priešingu atveju, klaidos pranešimą galime klaidingai bandyti apdoroti kaip duomenis.
GET metodasGET užklausa prašo serverio pateikti pasirinkto ištekliaus atvaizdą. Sėkminga užklausa dažniausiai grąžina:
200,GET užklausa nekeičia serverio duomenų. Dėl to tą pačią užklausą galima pakartoti norint iš naujo gauti duomenis.
Tai, kad duomenis techniškai galima pasiekti per API, dar nereiškia, kad juos galima naudoti be apribojimų. Reikia susipažinti su API naudojimo sąlygomis, licencija, privatumo reikalavimais ir užklausų skaičiaus ribojimais.
Atsakymas (angl. response) yra serverio klientui grąžinamas pranešimas. HTTP atsakymą paprastai sudaro trys dalys:
Pavyzdžiui, atsakymo antraštėje gali būti nurodyta:
Content-Type: application/json
Tai reiškia, kad atsakymo turinys pateiktas JSON formatu.
Kiekviena API gali turėti skirtingus išteklius, parametrus, autentifikavimo būdus ir atsakymo struktūrą. Todėl API dokumentacija yra praktiškai būtina. Net jeigu galinio taško adresą galima atspėti, be dokumentacijos negalime patikimai žinoti, kaip API turi būti naudojama.
Dokumentacijoje reikėtų rasti:
API dokumentacija apibrėžia kliento ir serverio komunikacijos taisykles. Kodas, kuris parašytas nesiremiant dokumentacija, gali veikti atsitiktinai, grąžinti ne visus duomenis arba nustoti veikti pasikeitus API.
JSON (angl. JavaScript Object Notation) yra tekstinis struktūrizuotų duomenų formatas. Jis plačiai naudojamas API atsakymams, nes yra gana lengvai perskaitomas žmogaus ir lengvai apdorojamas programų.
JSON formato struktūra remiasi:
{},[],Paprastas JSON objektas atrodo taip:
{
"id": 1,
"vardas": "Asta",
"aktyvus": true
}Objektą sudaro trys rakto ir reikšmės poros. Raktai yra id, vardas ir aktyvus. JSON reikšmės gali būti:
true arba false;null;Keli vienodos struktūros objektai gali būti pateikti masyve:
[
{
"id": 1,
"vardas": "Asta"
},
{
"id": 2,
"vardas": "Jonas"
}
]Tokią struktūrą dažnai galima tiesiogiai paversti R duomenų lentele: kiekvienas objektas tampa eilute (įrašu), raktai tampa stulpelių pavadinimais, o juos atitinkančios reikšmės lentelės langeliu.
JSON objektai gali būti įdėti vienas į kitą (nested):
{
"id": 1,
"vardas": "Asta",
"adresas": {
"miestas": "Vilnius",
"gatve": "Gedimino pr."
},
"kalbos": ["lietuvių", "anglų"]
}Šis pavyzdys nėra paprasta stačiakampė lentelė, nes rakto adresas reikšmė yra kitas objektas, o rakto kalbos reikšmė – masyvas. Todėl sudėtingesnis JSON atsakymas R aplinkoje dažnai pirmiausia tampa sąrašu, kurį vėliau reikia pertvarkyti.
Papildomai JSON struktūrą galima peržiūrėti vaizdo įraše „Learn JSON in 10 Minutes“. Svarbiausia atpažinti objektus {}, masyvus [] ir rakto bei reikšmės poras.
R
R aplinkoje HTTP užklausoms galima naudoti kelis paketus. Šiame skyriuje naudosime:
httr2 – HTTP užklausoms formuoti, siųsti ir atsakymams apdoroti,jsonlite – JSON tekstui paversti R objektais,dplyr ir tidyr – gautiems duomenims pertvarkyti.httr2 yra modernesnis httr paketo tęsinys. Vienas svarbiausių jo principų – užklausa pirmiausia sukuriama kaip objektas, tuomet nuosekliai papildoma keliu, parametrais, antraštėmis ar autentifikavimo informacija ir tik galiausiai išsiunčiama serveriui.
Paketus įdiegiame tik vieną kartą:
install.packages(c("httr2", "jsonlite", "dplyr", "tidyr"))Kiekvienos naujos R sesijos pradžioje paketus įkeliame:
httr2
Pagrindiniams pavyzdžiams naudosime viešą mokomąją JSONPlaceholder API. Jai nereikia registracijos ar autentifikavimo.
Tarkime, norime pasiimti naudotojų duomenis iš:
https://jsonplaceholder.typicode.com/users
Bazinę API adreso dalį galime saugoti atskirai:
pagrindinis_url <- "https://jsonplaceholder.typicode.com"Užklausa kuriama su funkcija request():
uzklausa <- request(base_url = pagrindinis_url)
uzklausaSukurtas objektas tik aprašo būsimą HTTP užklausą, todėl jis dar nėra išsiųstas serveriui. Prie bazinio adreso pridedame kelią iki ištekliaus:
uzklausa <- req_url_path(
req = uzklausa,
path = "/users"
)Nurodome HTTP metodą:
uzklausa <- req_method(
req = uzklausa,
method = "GET"
)Taigi užklausa buvo konstruojama trimis moduliariais žingsniais:
request()
↓
req_url_path()
↓
req_method()
↓
paruošta GET užklausa
O visas užklausos paruošimo kodas atrodo taip:
pagrindinis_url <- "https://jsonplaceholder.typicode.com"
uzklausa <- request(base_url = pagrindinis_url)
uzklausa <- req_url_path(req = uzklausa, path = "/users")
uzklausa <- req_method(req = uzklausa, method = "GET")|>
Ankstesnis kodas yra teisingas, tačiau nekompaktiškas. httr2 funkcijas patogu jungti bazinio R operatoriumi |>:
uzklausa <- request(base_url = pagrindinis_url) |>
req_url_path(path = "/users") |>
req_method(method = "GET")Kiekviena funkcija gauna ankstesniame žingsnyje sukurtą užklausą ir grąžina papildytą užklausos objektą.
GET?
httr2 pakete užklausos metodas pagal nutylėjimą yra GET, jeigu nėra pridedamas užklausos turinys. Todėl paprastai req_method(method = "GET") galima praleisti.
Mokantis API metodą kurį laiką nurodysime aiškiai, kad būtų matoma, kokio tipo HTTP užklausa siunčiama.
JSONPlaceholder leidžia kai kuriuos išteklius filtruoti užklausos parametrais. Pavyzdžiui, galime prašyti tik pirmojo naudotojo įrašų:
https://jsonplaceholder.typicode.com/posts?userId=1
Su httr2 užklausų parametrų nereikia rankiniu būdu jungti į URL tekstą. Tam naudojama funkcija req_url_query():
uzklausa <- request("https://jsonplaceholder.typicode.com") |>
req_url_path("/posts") |>
req_url_query(
userId = 1
)Jeigu užklausos parametro reikšmė saugoma objekte, galime perduoti funkcijų argumentams užklausos parametrų reikšmes.
vartotojo_id <- 1
uzklausa <- request("https://jsonplaceholder.typicode.com") |>
req_url_path("/posts") |>
req_url_query(
userId = vartotojo_id
)Vieno objekto identifikatorius dažnai yra ne užklausos parametras, o URL kelio dalis. Pavyzdžiui:
https://jsonplaceholder.typicode.com/users/3
Tokį adresą galima suformuoti taip:
vartotojo_id <- 3
uzklausa <- request("https://jsonplaceholder.typicode.com") |>
req_url_path("/users", vartotojo_id)Kuris būdas naudojamas konkrečioje API (kelio dalis ar užklausos parametras) visada turi būti tikrinama API dokumentacijoje.
Kai užklausa paruošta, ji išsiunčiama naudojant funkciją req_perform():
atsakymas <- req_perform(req = uzklausa)Suvykdžius komandą su šia funkcija, R iš tikrųjų susisiekia su serveriu ir perduoda sukonfiguruotą užklausą.
Ne visos API yra viešai prieinamos. Kai kurioms užklausoms serveris reikalauja autentifikavimo. Klientas turi pateikti informaciją, pagal kurią serveris gali patikrinti, ar užklausą leidžiama vykdyti.
Autentifikavimo mechanizmai gali būti įvairūs. Dažniausi pavyzdžiai:
Šiame skyriuje pagrindinis dėmesys skiriamas API rakto perdavimui. Praktiniam autentifikavimo pavyzdžiui naudosime MockAPI išteklių:
https://api.mockapi.com/vartotojai
API raktas yra serverio sugeneruota ar priskirta slapta reikšmė, kurią klientas pateikia kartu su užklausa. Pagal ją serveris gali atpažinti klientą, taikyti prieigos teises ar skaičiuoti naudojamų užklausų kiekį.
Pavyzdžiui, raktas gali atrodyti kaip ilga atsitiktinių simbolių seka:
f835e03be45644faa59cb49f093c6069
Svarbu žinoti ne kaip raktas turi atrodyti, o kur ir kokiu būdu API dokumentacija nurodo jį perduoti.
Pabandykime atlikti paprastą pavyzdį. Puslapis MockAPI leidžia susikurti testinę API su autentifikavimo raktu. Pirmiausia suformuojame įprastą GET užklausą:
pagrindinis_url <- "https://api.mockapi.com"
uzklausa <- request(base_url = pagrindinis_url) |>
req_url_path(path = "/vartotojai") |>
req_method(method = "GET")MockAPI dokumentacijoje autentifikavimas API raktu gali būti atliekamas dviem būdais.
x-api-key antraštėjeAPI raktą galima perduoti pasirinktinėje HTTP antraštėje:
x-api-key: MANO_API_RAKTAS
Su httr2 tam patogu naudoti req_headers_redacted():
uzklausa_auth1 <- req_headers_redacted(
.req = uzklausa,
"x-api-key" = "f835e03be45644faa59cb49f093c6069"
)req_headers_redacted() pažymi šios antraštės reikšmę kaip slaptą. Todėl spausdinant ar tikrinant užklausą pats raktas nėra rodomas.
Kitas būdas, tai tokeną perduoti standartinėje HTTP Authorization antraštėje:
Authorization: Bearer MANO_API_RAKTAS
Su httr2 tam skirta funkcija req_auth_bearer_token():
uzklausa_auth2 <- req_auth_bearer_token(
req = uzklausa,
token = "f835e03be45644faa59cb49f093c6069"
)Žodis Bearer pažodžiui išvertus reiškia turėtoją. Šios autentifikavimo schemos principas paprastas: prieiga suteikiama tam klientui, kuris pateikia galiojantį žetoną (tokeną). Bearer žetoną reikia saugoti panašiai kaip slaptažodį.
API raktas dažniausiai naudojamas identifikuoti programą ar sistemą, kuri kreipiasi į API, ir paprastai galioja ilgesnį laiką. API tokenas, kurio dažna forma yra Bearer tokenas, dažniau naudojamas konkrečiam naudotojui autentifikuoti ir gali turėti apibrėžtas prieigos teises bei ribotą galiojimo laiką.
x-api-key: <raktas>
arba:
Authorization: Bearer <raktas>
Kurį būdą naudoti, visada nurodo konkrečios API dokumentacija.
Tikro API rakto nerekomenduojama įrašyti tiesiai į .R, .Rmd ar .qmd, t. y. į šaltinio failą:
# NEREKOMENDUOJAMA
api_raktas <- "f835e03be45644faa59cb49f093c6069"Kodas gali būti persiųstas kitam žmogui, įkeltas į Git saugyklą ar publikuotas kartu su sugeneruotu HTML dokumentu.
Paprastas ir dažnai patogus būdas R projektuose – raktą laikyti aplinkos kintamajame .Renviron faile.
Naudotojo .Renviron failą patogu atidaryti su:
install.packages("usethis")
usethis::edit_r_environ()Faile įrašome:
MOCKAPI_KEY=f835e03be45644faa59cb49f093c6069
Po pakeitimo reikia iš naujo paleisti R sesiją. Tada raktą kode pasiimame iš sistemos aplinkos kintamųjų:
api_raktas <- Sys.getenv("MOCKAPI_KEY")
# patikrinimas, ar raktas nėra tuščias
if (identical(api_raktas, "")) {
stop("Nerastas aplinkos kintamasis `MOCKAPI_KEY`.")
}Ir naudojame užklausoje:
uzklausa <- request(base_url = pagrindinis_url) |>
req_url_path(path = "/vartotojai") |>
req_method(method = "GET") |>
req_auth_bearer_token(api_raktas)Tokiu būdu tikras raktas nėra įrašytas į šaltinio kodą.
Sys.setenv() nėra nuolatinio rakto saugykla
Techniškai galima vykdyti:
Sys.setenv(MOCKAPI_KEY = "mano_tikras_api_raktas")Tačiau jeigu tikrą raktą įrašome tiesiai į skriptą ar konsolės istoriją, jis vis tiek gali būti atskleistas. Ilgiau naudojamam raktui geriau naudoti .Renviron ar kitą saugią paslapčių saugyklą.
Prieš vykdant užklausą galima pasitikrinti, kas bus siunčiama serveriui:
req_dry_run(req = uzklausa)Naudojant Bearer autentifikavimą Authorization antraštės reikšmė bus paslėpta, pavyzdžiui:
GET /vartotojai HTTP/1.1
authorization: <REDACTED>
Grįžkime prie neautentifikuotos užklausos iš jsonplaceholder puslapio. Gautą atsakymą galima tiesiog išspausdinti, kur httr2 parodo svarbiausią informaciją.
atsakymas<httr2_response>
GET https://jsonplaceholder.typicode.com/users/3
Status: 200 OK
Content-Type: application/json
Body: In memory (520 bytes)
Atskiroms atsakymo dalims skirtos resp_*() funkcijos.
Galutinis URL:
resp_url(atsakymas)HTTP būsenos kodas:
resp_status(atsakymas)Būsenos tekstinis aprašymas:
resp_status_desc(atsakymas)Turinio tipas:
resp_content_type(atsakymas)Pavyzdžiui, sėkmingai JSON užklausai galime tikėtis:
200
application/json
Neapdorotą atsakymo turinį galima gauti kaip tekstinę eilutę:
ats_string <- resp_body_string(resp = atsakymas)
ats_stringJeigu turinys yra JSON, rezultatą galima perduoti jsonlite:
duomenys <- jsonlite::fromJSON(ats_string)
duomenys[1:4]Šis būdas aiškiai parodo du atskirus veiksmus ir jiems realizuoti naudojamus paketus:
httr2 paketas),R programoje JSON tekstas išanalizuojamas ir paverčiamas objektu (jsonlite paketas)httr2
httr2 jau turi funkciją resp_body_json(), todėl JSON nebūtina pirmiausia išsaugoti kaip tekstą:
atsakymas <- request("https://jsonplaceholder.typicode.com/users") |>
req_perform()
naudotojai <- resp_body_json(
resp = atsakymas,
simplifyVector = TRUE
)
naudotojai[1:4] id name username email
1 1 Leanne Graham Bret Sincere@april.biz
2 2 Ervin Howell Antonette Shanna@melissa.tv
3 3 Clementine Bauch Samantha Nathan@yesenia.net
4 4 Patricia Lebsack Karianne Julianne.OConner@kory.org
5 5 Chelsey Dietrich Kamren Lucio_Hettinger@annie.ca
6 6 Mrs. Dennis Schulist Leopoldo_Corkery Karley_Dach@jasper.info
7 7 Kurtis Weissnat Elwyn.Skiles Telly.Hoeger@billy.biz
8 8 Nicholas Runolfsdottir V Maxime_Nienow Sherwood@rosamond.me
9 9 Glenna Reichert Delphine Chaim_McDermott@dana.io
10 10 Clementina DuBuque Moriah.Stanton Rey.Padberg@karina.biz
Argumentas simplifyVector = TRUE nurodo, kad, kai įmanoma, JSON struktūra turėtų būti supaprastinta į R vektorius ar duomenų lenteles. Pavyzdžiui:
Jeigu pažvelgtume į funkcijos resp_body_json() vidų, pamatytume, kad viduje yra kviečiama fromJSON() funkcija iš jsonlite paketo. Kitaip tariant, resp_body_json() yra “wrapper” tipo funkcija.
API atsakymas ne visada yra paprasta stačiakampė lentelė. JSON gali turėti įdėtinių (nested) objektų. Tarkime, gautas objektas naudotojai turi stulpelį address, kuriame saugoma kita struktūra:
str(naudotojai)Stulpeliuose address ir company saugomos vidinės duomenų lentelės. Jas galima išskleisti paprastu būdu, kadangi fromJSON() funkcija sudėtinius objektus grąžina kaip lentelės stulpelius:
data.frame(
naudotojai[, colnames(naudotojai) != "address"],
"street" = naudotojai$address$street,
"suite" = naudotojai$address$suite,
"city" = naudotojai$address$city,
"zipcode" = naudotojai$address$zipcode,
"geo" = naudotojai$address$geo
) id name username email
1 1 Leanne Graham Bret Sincere@april.biz
2 2 Ervin Howell Antonette Shanna@melissa.tv
3 3 Clementine Bauch Samantha Nathan@yesenia.net
4 4 Patricia Lebsack Karianne Julianne.OConner@kory.org
5 5 Chelsey Dietrich Kamren Lucio_Hettinger@annie.ca
6 6 Mrs. Dennis Schulist Leopoldo_Corkery Karley_Dach@jasper.info
7 7 Kurtis Weissnat Elwyn.Skiles Telly.Hoeger@billy.biz
8 8 Nicholas Runolfsdottir V Maxime_Nienow Sherwood@rosamond.me
9 9 Glenna Reichert Delphine Chaim_McDermott@dana.io
10 10 Clementina DuBuque Moriah.Stanton Rey.Padberg@karina.biz
phone website company.name
1 1-770-736-8031 x56442 hildegard.org Romaguera-Crona
2 010-692-6593 x09125 anastasia.net Deckow-Crist
3 1-463-123-4447 ramiro.info Romaguera-Jacobson
4 493-170-9623 x156 kale.biz Robel-Corkery
5 (254)954-1289 demarco.info Keebler LLC
6 1-477-935-8478 x6430 ola.org Considine-Lockman
7 210.067.6132 elvis.io Johns Group
8 586.493.6943 x140 jacynthe.com Abernathy Group
9 (775)976-6794 x41206 conrad.com Yost and Sons
10 024-648-3804 ambrose.net Hoeger LLC
company.catchPhrase
1 Multi-layered client-server neural-net
2 Proactive didactic contingency
3 Face to face bifurcated interface
4 Multi-tiered zero tolerance productivity
5 User-centric fault-tolerant solution
6 Synchronised bottom-line interface
7 Configurable multimedia task-force
8 Implemented secondary concept
9 Switchable contextually-based project
10 Centralized empowering task-force
company.bs street suite
1 harness real-time e-markets Kulas Light Apt. 556
2 synergize scalable supply-chains Victor Plains Suite 879
3 e-enable strategic applications Douglas Extension Suite 847
4 transition cutting-edge web services Hoeger Mall Apt. 692
5 revolutionize end-to-end systems Skiles Walks Suite 351
6 e-enable innovative applications Norberto Crossing Apt. 950
7 generate enterprise e-tailers Rex Trail Suite 280
8 e-enable extensible e-tailers Ellsworth Summit Suite 729
9 aggregate real-time technologies Dayna Park Suite 449
10 target end-to-end models Kattie Turnpike Suite 198
city zipcode geo.lat geo.lng
1 Gwenborough 92998-3874 -37.3159 81.1496
2 Wisokyburgh 90566-7771 -43.9509 -34.4618
3 McKenziehaven 59590-4157 -68.6102 -47.0653
4 South Elvis 53919-4257 29.4572 -164.2990
5 Roscoeview 33263 -31.8129 62.5342
6 South Christy 23505-1337 -71.4197 71.7478
7 Howemouth 58804-1099 24.8918 21.8984
8 Aliyaview 45169 -14.3990 -120.7677
9 Bartholomebury 76495-3109 24.6463 -168.8889
10 Lebsackbury 31428-2261 -38.2386 57.2232
Bet toks būdas nepatogus, jeigu sudėtinis objektas turi daugiau nei kelis vidinius objektus. Bendruoju atveju, paprasčiau tą patį galima atlikti naudojant unnest_wider() funkciją iš tidyr paketo:
Jeigu address yra sąrašo tipo stulpelis, jį galima išskleisti su tidyr::unnest_wider():
naudotojai_tvarkingi <- naudotojai |>
tidyr::unnest_wider(
col = address,
names_sep = "_"
)Jeigu išskleistoje struktūroje lieka dar vienas įdėtinis objektas, jį galima išskleisti pakartotinai:
naudotojai_tvarkingi <- naudotojai_tvarkingi |>
tidyr::unnest_wider(
col = address_geo,
names_sep = "_"
)JSON gali aprašyti hierarchinius duomenis, todėl nereikėtų tikėtis, kad kiekvienas API atsakymas automatiškai taps viena tvarkinga duomenų lentele. Pirmiausia patikrinkite objektą su str(), o tik tada pasirinkite pertvarkymo veiksmus.
Jeigu atsakymas labai didelis, jo nebūtina pirmiausia laikyti R darbinėje atmintyje. req_perform() argumentu path galima nurodyti failą, į kurį atsakymo turinys turi būti išsaugotas:
atsakymas <- req_perform(
req = uzklausa,
path = "../jsonplaceholder-users.json"
)Tokiu atveju serverio grąžintas turinys įrašomas tiesiai į JSON failą, kurį galbūt norėsime apdoroti vėliau.
Tai ypač naudinga, nes API duomenys laikui bėgant gali pakisti. Siekiant atkartojamumo naudinga išsaugoti ne tik pradinį serverio atsakymą, bet ir užklausos datą ir laiką, naudotus parametrus, API versiją ir HTTP būsenos kodą.
Pavyzdžiui, kreipiantis į neegzistuojantį galinį tašką:
request("https://jsonplaceholder.typicode.com") |>
req_url_path("/neegzistuojantis-isteklius") |>
req_perform()httr2 pagal nutylėjimą 4xx ir 5xx atsakymus paverčia klaidomis R kalboje. Tai apsaugo nuo situacijos, kai klaidos atsakymas netyčia pradedamas apdoroti kaip tikras duomenų rinkinys.
Jeigu vykdome daug užklausų ir nenorime, kad viena klaida nutrauktų visą kodo procesą ar eigą, galime naudoti konstrukciją su tryCatch(). Tokiu atveju, klaidą paverčiame tik įspėjimu, nes įprastai klaidų nereikėtų ignoruoti:
saugiai_gauti_json <- function(url) {
tryCatch(
{
request(url) |>
req_perform() |>
resp_body_json(simplifyVector = TRUE)
},
error = function(e) {
warning("API užklausa nepavyko: ", conditionMessage(e))
NULL
}
)
}
saugiai_gauti_json("https://jsonplaceholder.typicode.com/neegzistuojantis-endpoint")Dideli duomenų rinkiniai dažnai negrąžinami vienu atsakymu. API gali padalyti rezultatus į mažesnes dalis arba puslapius (angl. pagination).
Skirtingos API puslapiavimą realizuoja skirtingai. Galima sutikti tokius parametrus kaip:
page – puslapio numeris,limit arba per_page – įrašų skaičius puslapyje,offset arba start – kiek įrašų praleisti,cursor – serverio grąžinama žymė kitai rezultatų daliai.JSONPlaceholder /posts ištekliuje yra 100 įrašų. Galime paprašyti ne visų įrašų iš karto, o, pavyzdžiui, 10 įrašų nuo 21-ojo:
https://jsonplaceholder.typicode.com/posts?_start=20&_limit=10
Su httr2:
atsakymas <- request("https://jsonplaceholder.typicode.com") |>
req_url_path("/posts") |>
req_url_query(
`_start` = 20,
`_limit` = 10
) |>
req_perform()
irasai_21_30 <- resp_body_json(
atsakymas,
simplifyVector = TRUE
)Parametrų _start ir _limit pavadinimai yra JSONPlaceholder pasirinkimas. Kita API gali naudoti page, offset, cursor arba kitą mechanizmą. Puslapiavimo logiką visada reikia tikrinti konkrečios API dokumentacijoje.
Taigi, bendra httr2 darbo eiga, komunikuojant su serveriu per API, atrodo taip:
request()
↓
req_*() funkcijos
↓
paruošta užklausa
↓
req_perform()
↓
serveris
↓
atsakymas
↓
resp_*() funkcijos
Šių užduočių tikslas – savarankiškai perskaityti API dokumentaciją, pasirinkti tinkamą galinį tašką, suformuoti užklausą ir paruošti analizavimui tinkamus duomenis.
Naudokite Lietuvos hidrometeorologijos tarnybos API dokumentaciją: https://api.meteo.lt/.
httr2 gaukite šį sąrašą ir paverskite jį R duomenų objektu.Sprendimuose turi būti aiškiai atskirta:
R objektu,Naudodami 1 užduotyje pasirinktą vietovę atlikite sekančias užduotis.
request() ir req_*() tipo funkcijas.Parašykite savo funkciją, kuri kaip argumentą priima vietovės kodą ir per Meteo.lt API grąžina tos vietovės ilgalaikės prognozės duomenų lentelę.
Pasirinkite Vilnių, Kauną ir Klaipėdą. Naudodami šią funkciją atlikite šias užduotis.
Atidarykite Lietuvos duomenų API dokumentaciją: https://lt-api.lt/dokumentacija.
Dar neatlikdami užklausos:
GET galinį tašką, kuris būtų įdomus duomenų analizei.R duomenų rinkinį iš šio galinio taško būtų galima sudaryti ir kokį analitinį klausimą su juo būtų galima nagrinėti.Susikurkite paskyrą https://lt-api.lt/ ir sugeneruokite API raktą. Dokumentacijoje nurodyta, kad raktas siunčiamas kaip Bearer tokenas:
Authorization: Bearer JUSU_API_RAKTAS
.R failą. Išsaugokite jį .Renviron faile, pavyzdžiui, kintamuoju LT_API_KEY.R kode raktą nuskaitykite su Sys.getenv().GET galinį tašką ir atlikite autentifikuotą užklausą su req_auth_bearer_token().req_dry_run() ir įsitikinkite, kad autentifikavimo reikšmė konsolėje nėra atskleidžiama.R objektu ir iš jo paruoškite nedidelę analizei tinkamą lentelę.Jeigu užduoties atlikimo metu negalite susikurti rakto ar pasirinktas galinis taškas neprieinamas pagal jūsų planą, paruoškite pilną httr2 užklausos kodą su Sys.getenv("LT_API_KEY") ir paaiškinkite, kokios HTTP antraštės tikisi serveris bei kokio tipo atsakymo tikėtumėtės pagal dokumentaciją. Tikro rakto į darbą nekelkite.
API yra standartizuota sąsaja, leidžianti klientui bendrauti su serveriu. Klientas siunčia HTTP užklausą į konkretų išteklių, o serveris grąžina HTTP atsakymą. Duomenims gauti dažniausiai naudojamas GET metodas.
Naudojant httr2, užklausa pirmiausia sukuriama funkcija request(), tada keičiama ir papildoma req_*() funkcijomis, o į serverį išsiunčiama su req_perform(). Serverio atsakymo informacijai ir turiniui apdoroti naudojamos resp_*() funkcijos.
API duomenys dažnai pateikiami JSON formatu. resp_body_json() leidžia JSON atsakymą tiesiogiai paversti R objektu, o resp_body_string() leidžia pamatyti pradinį tekstinį atsakymą.
Neviešoms API gali būti reikalingas autentifikavimas. API raktas gali būti perduodamas pasirinktinėje HTTP antraštėje, pavyzdžiui, x-api-key, arba kaip Bearer tokenas standartinėje Authorization antraštėje. Kurį būdą naudoti, visada nustato API dokumentacija.
API raktų nereikėtų rašyti tiesiai į analizės kodą. Paprastame R projekte juos patogu laikyti .Renviron faile ir nuskaityti su Sys.getenv().
httr2. Perform HTTP Requests and Process the Responses.httr2. Wrapping APIs.