Arvutiteaduse instituut
  1. Kursused
  2. 2023/24 kevad
  3. Veebiteenuste ja hajussüsteemide arendus (LTAT.06.018)
EN
Logi sisse

Veebiteenuste ja hajussüsteemide arendus 2023/24 kevad

  • Pealeht
  • Loengud
  • Praktikumid
  • Lahenduste Esitamine

Neljas praktikum - RESTful APIde loomine

Selles praktikumis loome REST API raamatute alla laadimiseks Gutenbergist (serverisse), raamatute sisu küsimiseks serverist ja raamatute haldamiseks ning sõnede otsimiseks raamatust. REST API loomiseks kasutame Python Flask raamistiku, mis pakub lihtsat liidest REST veebiteenuste loomiseks.

Viited

  1. Python Flask raamistik - https://flask.palletsprojects.com/en/2.0.x/
  2. Python Flask minimaalne näide: https://flask.palletsprojects.com/en/2.0.x/quickstart/#a-minimal-application

Probleemide korral kontrollige:

  1. Võimalikud probleemid ja nende potentsiaalsed lahendused osa praktikumi juhendi lõpus.
  2. Küsige otse #praktikum-4-rest Zulipi teemas.
    • Ka siis kui soovite lihtsalt vihjeid.

Ülesanne 4.1: Ettevalmistavad tegevused

Kasutame ka selles praktikumis Python PyCharm IDE'd. Selles ülesandes seadistame valmis Pycharm projekti ning tutvume rakenduse näitekoodiga ning sellega kuidas välja kutsuda REST GET päringuid näite programmi "vastu".

  • Looge uus PyCharm Python'i projekt.
  • Tõmmake alla näitekood rest_example.py
    • Kasutage brauseri parem klikki ning "Save as" valikut. Siis ei lähe eesti tähed "katki"
  • Tutvuge näitekoodiga
  • Installeerige puuduvad paketid.
  • Jooksutage programmi ja kontrollige, et see töötab korrektselt.
    • Saadame GET päringu programmi REST API vastu pordile 5000 ja ressursile /raamatud
      • Tehke seda kõigepealt brauseri kaudu:
        • Avage lehekülg: http://localhost:5000/raamatud
      • Seejärel proovige käsurea kaudu:
        • Windowsis saate kasutada PowerShell'i:
          • Invoke-RestMethod -Uri "http://localhost:5000/raamatud" -Method 'Get'
        • Linuksis saate käsureal kasutada curl käsku: curl http://localhost:5000/raamatud

Eduka käivituse tulemusena peaks tagastama JSON objekti, mille sees on sõnum: "GET päring /raamatud REST lõpp punkti õnnestus!"

Ülesanne 4.2: REST meetod raamatute nimekirja vaatamiseks

Selles ülesandes muudame näite rakenduse REST GET meetodit nii, et see tagastaks rakenduse poolt hallatavate raamatute nimekirja (JSON andmestruktuurina). Ning valmistame (esialgu) käsitsi ette paar raamatut serverisse testimiseks.

  • Looge kaust raamatud PyCharm projekti sees. Siia salvestab edaspidi meie programm raamatute failid.
  • Modifitseerige meetodit raamatu_nimekiri()
    • See meetod on serveris kätte saadav aadressil /raamatud, GET REST meetodi kaudu.
  • Kirjutage kood, mis genereerib nimekirja kaustas raamatud eksisteerivatest failidest
    • Failide nimekirja saamiseks saab kasutada Python meetodit: os.listdir(kaust)
    • Saate luua tühja raamatud listi ning sellesse lisada raamatu ID iga faili kohta raamatu_nimekiri() mis leidub kaustas, ning mis lõppeb .txt laiendiga
      • Pange listi ainult raamatu ID, eemaldades faili nime lõpust ".txt".
        • Vihje: lihtne viis eemaldada ".txt" on kasutada Pythons tring split() operatsiooni, määrates eraldajaks punkti ".", ja tulemuse listist võtta vaid esimene väärtus.
  • Meetod peaks tagastama JSON formaadis tulemuse, mis sisaldab võtit "raamatud", mille väärtuseks on raamatute ID'de list.
    • Lisaks võiks tagastada HTTP koodi "OK" (200).
      • HTTP koode saab määrata return käsu teise argumendina.
    • Näide:
          return ({
              "raamatud": raamatud
          }, 200 )
  • Kontrollige, et tulemus on korrektne. Tehke GET päring serverisse /raamatud aadressil.
    • Testimiseks saate esialgu kausta luua uue tekst faili nimega: 12345.txt
      • Või Testimiseks sinna käsitsi liigutada paar Gutenberg raamatu faili, mida olete varasemates praktikumides salvestanud.
    • Näide oodatud tulemusest:

NB! Salvesta ülesande lahendusena ekraanivaade selle REST meetodi väljakutsumisest. Seal peaks olema näha viis, kuidas ja mis meetodit välja kutsuti (brauser või käsurida) ning tagastatud väljund.

Ülesanne 4.3: REST meetod raamatu vaatamiseks/allatõmbamiseks

Loome REST API GET meetodi, mis võimaldab alla laadida olemasoleva raamatu sisu. Meetod saab sisendiks raamatu ID, ning tagastab raamatu sisu.

  • Looge uus Python meetod raamatu_allatombamine(book_id):
    • @app.route('/raamatud/<book_id>', methods = ['GET'])
      def raamatu_allatombamine(book_id):
      • See meetod on serveris kätte saadav aadressil /raamatud/BOOK_ID, GET REST meetodi kaudu. Kus BOOK_ID on raamatu Gutenberg ID.
  • See meetod saab argumendiks raamatu ID (book_id)
  • Meetod peaks kontrollima, kas raamatute kaustas on sellele ID'le vastav raamatu fail book_id.txt
    • Kui ei ole sellist faili, siis peaks tagastama tühja JSON dokumendi {} ning HTTP koodi 404 (NOT FOUND).
    • Kui fail leidub, siis peaks tagastama raamatu sisu
      • Faili saab meetodi tulemusena lihtsasti tagastada kasutades Flask meetodit send_file()
      • Importige see meetod: from flask import send_file
      • return (send_file(faili_nimi, mimetype='text/plain'), 200)
        • Kasutame HTTP koodi 200 märkimaks, et päring õnnestus.
        • Kasutame mimetype='text/plain' määramaks, et tegemist on tavalise tekstifailiga.
    • Samuti peaks kontrollima, et meetodi argument on int tüüpi muutuja!
      • On tähtis kontrollida, et päringu kaudu saadetakse korrektne sisend, muidu võib juhtuda, et kavalal ründajal õnenstub serverist mõndasid teisi faile vaadata.
      • Seda saab teha näiteks nii: not book_id.isnumeric()
    • Näide oodatud tulemusest:

NB! Salvesta ülesande lahendusena ekraanivaade selle REST meetodi väljakutsumisest. Seal peaks olema näha viis, kuidas ja mis meetodit välja kutsuti (brauser või käsurida) ning tagastatud väljund.

Ülesanne 4.4: REST meetod raamatu kustutamiseks

Loome REST API DELETE meetodi selleks, et saaks olemasolevaid raamatuid kustutada.

  • Loome meetodi raamatu_kustutamine(book_id):
    • @app.route('/raamatud/<book_id>', methods = ['DELETE'])
      def raamatu_kustutamine(book_id):
    • Meetodi argumendiks on raamatu ID (book_id).
    • Meetodi REST tüübiks on DELETE ja REST lõpp-punktiks /raamatud/BOOK_ID
    • Meetod peaks kontrollima, kas selle ID'ga raamatu fail eksisteerib raamatu failide seas ning:
      • Selle kustutama, kui see eksisteerib, ning väljastama tühja JSON struktuuri {} ning HTTP koodi 204.
      • Kui faili ei eksisteeri, peaks tagastama Tühja JSON struktuuri {} ning HTTP koodi 404 (Not Found).
    • Samuti peaks kontrollima, et meetodi argument on int tüüpi muutuja!
      • On tähtis kontrollida, et päringu kaudu saadetakse korrektne sisend, Muidu võib juhtuda, et kavalal ründajal õnenstub serverist mõndasid teisi faile kustutada.
      • Seda saab kontrollida näiteks nii: not book_id.isnumeric()
      • Kui ei ole sisendparameeter korrektne, siis peaks programm tagastama Tühja JSON struktuuri {} ning HTTP koodi 400 (Bad Request).
  • Testige, et meetod töötab saates REST DELETE päring serveri REST API lõpp-punkti /raamatud/book_id.
    • Windowsi näide: Invoke-RestMethod -Uri http://localhost:5000/raamatud/12345 -Method 'Delete'
    • Linuksi näide: curl -X "DELETE" http://localhost:5000/raamatud/12345
  • Programmi eduka töö korral kustutatakse fail.

NB! Salvesta ülesande lahendusena ekraanivaade selle REST meetodi väljakutsumisest. Seal peaks olema näha viis, kuidas ja mis meetodit välja kutsuti ning tagastatud väljund.

Ülesanne 4.5: REST meetod failide alla tõmbamiseks Gutenbergist

Loome REST API POST serveri meetodi, millele saab saata raamatu ID, mille peale server tõmbab sellele ID'le vastava raamatu Gutenberg repositooriumist alla ning salvestab raamatute kausta.

  • Loome meetodi:
    • @app.route('/raamatud', methods = ['POST'])
      def raamatu_lisamine():
    • See meetod on serveris kätte saadav aadressil /raamatud, POST REST meetodi kaudu.
    • Meetodi sisuks on JSON andmestruktuur, mis sialdab raamatu Gutenberg ID'd
      • Näide andmetest, mida saadetakse: {"raamatu_id": "12345"}
      • Näide meetodi välja kutsumisest:
        • Windowsis:
          • Invoke-RestMethod -Uri "http://localhost:5000/raamatud" -Method 'Post' -Body '{"raamatu_id": "12345"}' -ContentType "application/json"
        • Linuksis:
          • curl -X POST -H "Content-Type: application/json" --data '{"raamatu_id": "12345"}' http://localhost:5000/raamatud
  • Meetod peaks lugema sisse raamatu ID:
    input = json.loads(request.data)
    book_id = input['raamatu_id']
  • Meetod peab alla laadima raamatu Gutenberg serverist (vastavalt raamatu ID väärtusele) ning selle salvestama raamatute kausta nimega: raamatu_id.txt
    • Saate kasutada varasemate praktikumides loodud koodi raamatu alla laadimiseks Gutenbergist ning selle salvestamist failina.
  • Kui õnnestub raamat alla laadida, peaks meetod peaks tagastama:
    • tulemuse JSON kujul. Näide:
      {"tulemus": "Raamatu loomine õnnestus",
                  "raamatu_id": 12345 }
    • HTTP koodi 201 (Created)
  • Programmi eduka töö korral luuakse uus fail raamatute kausta.

NB! Salvesta ülesande lahendusena ekraanivaade selle REST meetodi väljakutsumisest. Seal peaks olema näha viis, kuidas ja mis meetodit välja kutsuti (brauser või käsurida) ning tagastatud väljund.

Ülesanne 4.6: REST meetod failist sõne otsimiseks

Loome REST API meetodi selleks, et saaks serveris asuvast raamatust sõnet otsida. REST meetod saab argumendiks raamatu id ja sõne ning tagastab loenduri, mis näitab mitu korda see sõne selles raamatus esines. See meetod ei tohi raamatut uuesti alla tõmmata Gutenbergist, vaid peaks otsima sõnet ainult serveris juba olevast raamatust.

  • Loome meetodi:
    • @app.route('/raamatu_otsing', methods = ['POST'])
      def raamatust_sone_otsimine():
      • See meetod on serveris kätte saadav aadressil /raamatu_otsing, POST REST meetodi kaudu.
    • Meetodi sisuks on JSON andmestruktuur, mis sialdab raamatu Gutenberg ID'd ning otsingu sõne
      • Näide andmetest, mida saadetakse: {"raamatu_id": "122", "sone": "estonia"}
      • Näide meetodi välja kutsumisest:
        • Invoke-RestMethod -Uri "http://localhost:5000/raamatu_otsing" -Method 'Post' -Body '{"raamatu_id": "122", "sone": "estonia"}' -ContentType "application/json"
  • Meetod peaks lugema sisse raamatu ID:
    input = json.loads(request.data)
    sone = input['sone']
    raamatu_id =  input['raamatu_id']
  • Meetod peab avama vastava raamatu faili ning, sealt otsima määratud sõne leidumist ning arvutama kokku, mitu korda see sõne seal leidus
    • Saate kasutada varasemate praktikumides loodud koodi raamatust sõne otsimiseks. Aga kindlasti peab otsima juba alla laetud failist raamatute kaustas.
  • Kui raamat leidub, peaks meetod peaks tagastama:
    • tulemuse JSON kujul. Näide:
      {"raamatu_id": 122,
      "sone": "and",
      "leitud": 226 }
    • HTTP koodi 200 (OK)
  • Kui raamatut ei leidu, siis tuleks tagastada HTTP kood 404 (Not Found) ja tühi JSON {}

NB! Salvesta ülesande lahendusena ekraanivaade selle REST meetodi väljakutsumisest. Seal peaks olema näha viis, kuidas ja mis meetodit välja kutsuti (käsurida) ning tagastatud väljund.

Lahenduse esitamine

Praktikumi lahendusena tuleb esitada:

  1. Python kood, mis valmis praktikumi lõpuks.
    • NB! Ei pea iga ülesande lahendust eraldi salvestama.
  2. Ekraanivaated ülesannetest 4.2-4.6.
  3. Failid tuleks kokku pakkida üheks Zip failiks enne üles laadimist.
    • Lahendusega ei tohi kaasa panna virtuaalkeskkonna kaustasid (nt. .venv, .env, venv)
Lahenduste esitamiseks peate olema sisse loginud ja kursusele registreerunud.

Võimalikud probleemid ja nende potentiaalsed lahendused.

  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused