18  Duomenų gavimas naudojant API

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:

18.1 Kas yra API?

API galima suprasti kaip iš anksto apibrėžtą taisyklių rinkinį, pagal kurį viena programa gali bendrauti su kita programa. API nurodo:

  • kokių duomenų arba veiksmų galima prašyti,
  • kokiu adresu siųsti užklausą,
  • kokius parametrus galima ar būtina pateikti,
  • kaip turi būti patvirtinta naudotojo tapatybė,
  • kokio formato atsakymas bus grąžintas,
  • kokios klaidos gali atsirasti.

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ų.

Klientas ir serveris

API komunikacija paprastai vyksta tarp dviejų pusių:

  • kliento – programa, kuri siunčia užklausą (mūsų atveju klientas bus R),
  • serverio – kompiuteris arba sistema, kuri priima užklausą, ją apdoroja ir grąžina atsakymą.

Bendra komunikacijos eiga yra tokia:

  1. klientas suformuoja užklausą su kreipimuosi dėl norimo ištekliaus,
  2. užklausa internetu nusiunčiama serveriui,
  3. serveris patikrina užklausą ir atlieka prašomą veiksmą,
  4. serveris grąžina atsakymą,
  5. klientas patikrina atsakymą ir toliau naudoja jo turinį.

Šaltinis: https://www.postman.com/what-is-an-api/

Šį 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

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.

PastabaURI ir URL

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

Užklausa (angl. request) yra kliento siunčiamas pranešimas serveriui. Užklausoje nurodoma:

  • į kokį išteklių kreipiamasi,
  • koks veiksmas turi būti atliktas,
  • kokie papildomi parametrai perduodami,
  • prireikus, ir autentifikavimo informacija,
  • kai kurių metodų atveju – siunčiami duomenys.

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.

Užklausos parametrai

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
  • išteklius yra /comments;
  • parametro pavadinimas yra postId;
  • parametro reikšmė yra 1.

Keliais parametrais papildytas adresas galėtų atrodyti taip:

https://api.example.com/data?year=2025&region=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 metodai

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.

HTTP būsenos kodai

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 metodas

GET užklausa prašo serverio pateikti pasirinkto ištekliaus atvaizdą. Sėkminga užklausa dažniausiai grąžina:

  • HTTP būsenos kodą 200,
  • atsakymo antraštes,
  • atsakymo turinį, dažniausiai JSON formatu.

GET užklausa nekeičia serverio duomenų. Dėl to tą pačią užklausą galima pakartoti norint iš naujo gauti duomenis.

ĮspėjimasDuomenų naudojimo sąlygos

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.

Serverio/API atsakymas

Atsakymas (angl. response) yra serverio klientui grąžinamas pranešimas. HTTP atsakymą paprastai sudaro trys dalys:

  1. būsenos kodas – nurodo, ar užklausa įvykdyta sėkmingai,
  2. antraštės – pateikia informaciją apie atsakymą, pavyzdžiui, turinio tipą,
  3. turinys (angl. body) – grąžinti duomenys arba klaidos aprašymas.

Pavyzdžiui, atsakymo antraštėje gali būti nurodyta:

Content-Type: application/json

Tai reiškia, kad atsakymo turinys pateiktas JSON formatu.

API dokumentacija

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:

  • bazinį API adresą,
  • galimus galinius taškus,
  • kiekvieno galinio taško palaikomus HTTP metodus,
  • privalomus ir pasirenkamus parametrus,
  • parametrų tipus ir leistinas reikšmes,
  • autentifikavimo tvarką,
  • grąžinamo atsakymo pavyzdį ir duomenų laukų paaiškinimus,
  • galimus būsenos kodus ir klaidas,
  • puslapiavimo taisykles,
  • užklausų skaičiaus ribojimus,
  • duomenų licenciją ir naudojimo sąlygas.
SvarbuDokumentacija yra API sutartis

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.

18.2 Kas yra JSON?

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:

  • objektais, rašomais riestiniuose skliaustuose {},
  • rakto ir reikšmės poromis, kurios sudaro objektų turinų,
  • masyvais, rašomais laužtiniuose skliaustuose [],
  • įdėtinėmis struktūromis.

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:

  • tekstas, rašomas dvigubose kabutėse;
  • skaičius;
  • loginė reikšmė true arba false;
  • tuščia reikšmė null;
  • objektas;
  • masyvas.

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.

PatarimasJSON struktūros suvokimas

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.

## API užklausos naudojant R
city: Klaipėda [1] 16.39167

city: Vilnius [1] 13.80417



:::
:::


:::
:::
::::

## 4 užduotis. API dokumentacijos analizė {.unnumbered}

Atidarykite Lietuvos duomenų API dokumentaciją:
<https://lt-api.lt/dokumentacija>.

Dar neatlikdami užklausos:

1. Raskite bent tris skirtingas išteklių grupes.
2. Pasirinkite vieną `GET` galinį tašką, kuris būtų įdomus duomenų analizei.
3. Nustatykite:
   - bazinį API adresą,
   - galinio taško kelią,
   - kokie parametrai galimi arba privalomi,
   - kokia atsakymo struktūra,
   - ar reikia autentifikavimo,
   - kaip autentifikavimo informacija turi būti perduodama.
4. Trumpai paaiškinkite, kokį `R` duomenų rinkinį iš šio galinio taško būtų
   galima sudaryti ir kokį analitinį klausimą su juo būtų galima nagrinėti.


## 5 užduotis. Autentifikuota užklausa į Lietuvos API {.unnumbered}

Susikurkite paskyrą <https://lt-api.lt/> ir sugeneruokite API raktą. 
Dokumentacijoje nurodyta, kad raktas siunčiamas kaip Bearer tokenas:

``` text
Authorization: Bearer JUSU_API_RAKTAS
  1. Rakto nerašykite tiesiai į .R failą. Išsaugokite jį .Renviron faile, pavyzdžiui, kintamuoju LT_API_KEY.
  2. R kode raktą nuskaitykite su Sys.getenv().
  3. Iš Lietuvos API dokumentacijos pasirinkite vieną jums prieinamą GET galinį tašką ir atlikite autentifikuotą užklausą su req_auth_bearer_token().
  4. Prieš vykdydami užklausą panaudokite req_dry_run() ir įsitikinkite, kad autentifikavimo reikšmė konsolėje nėra atskleidžiama.
  5. Patikrinkite atsakymo būseną ir turinio tipą.
  6. JSON turinį paverskite R objektu ir iš jo paruoškite nedidelę analizei tinkamą lentelę.
  7. Pakeiskite vieną užklausos parametrą ir paaiškinkite, kaip dėl to pasikeitė grąžintas rezultatas.
PastabaJei Lietuvos API raktas nepasiekiamas

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.

18.3 Skyriaus santrauka

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().

Naudoti ir papildomi šaltiniai