Institute of Computer Science
  1. Courses
  2. 2023/24 spring
  3. Development of web services and distributed systems (LTAT.06.018)
ET
Log in

Development of web services and distributed systems 2023/24 spring

  • Pealeht
  • Loengud
  • Praktikumid
  • Lahenduste Esitamine

Viies praktikum - REST OpenAPI

Selles praktikumis loome OpenAPI spetsifikatsiooni eelmise praktikumis loodud REST API jaoks. Seejärel genereerime OpenAPI generaatori abil serveri koodi projekti, implementeerime loodud meetodid (eelmise praktikumi koodi uuesti kasutades) ning testime lahendust kasutades OpenAPI poolt genereeritud Kasutajaliidest meie API'le.

Viited

  1. OpenAPI 3.1 spetsifikatsioon ja näited: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject
  2. OpenAPI generaator: https://github.com/OpenAPITools/openapi-generator
  3. OpenAPI generaatori veebiteenus: http://api.openapi-generator.tech/index.html
  4. YAML dokumentide valideerija ja vigade kontroll: https://onlineyamltools.com/validate-yaml

Probleemide korral kontrollige:

  1. Võimalikud probleemid ja nende potentsiaalsed lahendused osa praktikumi juhendi lõpus.
  2. Küsige otse #praktikum-5-openapi Zulip teemas.
    • Ka siis kui soovite lihtsalt viheid.

Tähtsad asjad, mida meeles pidada

  1. OpenAPI generaator, mida selles praktikumis kasutame loob uue koopia serveri koodist. Olge ettevaatlikud koodi üle kirjutamisega, muidu kaotate muudetud failides tehtud täiendused.
    • NB Tehke serveri koodis muudetud failidest koopiad enne kaustade üle kirjutamist!!
  2. Olge aktiivsed praktikumijuhendajalt abi küsimises, kui tekib probleeme, mille põhjust on raske leida. Probleemid võivad olla YAML failis, python koodis, või teekide installeerimises.

Ülesanne 5.1: OpenAPI spetsifikatsioon

Selles ülesandes uurime OpenAPI spetsifikatsiooni, mis vastab suuresti eelmises praktikumis loodud veebiteenusele.

  • Laadige alla OpenAPI spetsifikatsiooni fail: veebiteenus.yaml
  • Tutvuge selle sisuga.
    • See on YAML tüüpi fail, mis sialdab paths: blokis kirjeid veebiteenuse lõpp-punktide kohta ja nendes toetatud HTTP operatsioonide (GET, PUT, POST, DELETE) kohta. Operatsioonide jaoks on defineeritud ka vajalikud sisendid (ning nende struktuur), oodatud väljundid, näite sisendid.
    • Selles on puudu ühe operatiooni kirje (/raamatud/{bookId} GET), mille te lisate siia hilisema ülesande raames ise juurde.

Ülesanne 5.2: OpenAPI generaator

Kasutame OpenAPI generaatorit, et genereerida ApenAPI spetsifikatsioonile vastava veebiteenuse serveri koodi Pythonis, Flask raamistiku jaoks. OpenAPI generaatorit saab kasutada mitmel erineval viisil. Näiteks veebiteenusena välja kutsuda, installeerida see enda arvutis iseseisva tarkvarana või Docker konteineris.

  • OpenAPI generaatori kasutamine Java rakendusena
    • Selle lahenduse jaoks peab Java versioon 11+ olema installeeritud ning käsurealt kasutatav.
      • Näiteks Java 17 töödab ok.
        • https://www.oracle.com/java/technologies/downloads/#jdk17-windows
      • Selleks et Javat käsurealt kasutada on vajalik, et java /bin kaust peab olema süsteemi keskkonna mutuja PATH sees seadistatud. Tavaliselt seadistatakse see automaatselt kui Java installeerida.
        • Kui sovite rohkem infot JAVA asukoha seadistamiseks Windows'is: https://www.geeksforgeeks.org/how-to-set-java-path-in-windows-and-linux/
    • Tõmmake alla OpenAPI generaatori java rakendus aadressilt: https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.4.0/openapi-generator-cli-7.4.0.jar
    • Valmistage ette kaust, kus liigutage openapi-generator-cli-7.4.0.jar ning veebiteenus.yaml failid
    • Käivitage käsurealt (samas kaustas!) OpenAPI java programmina: java -jar openapi-generator-cli-7.4.0.jar generate -i veebiteenus.yaml --package-name raamatu_teenus -g python-flask -o python-flask-server-generated
      • Tulemusena genereeritakse kaust python-flask-server-generated
      • NB! Ärge kasutage otse python-flask-server-generated kausta, kuna siis on suur oht, et hiljem generaatorit uuesti kasutades kirjutate üle failid kuhu olete teinud muudatusi!
      • Kopeerige (või nimetage ümber) python-flask-server-generated kaust üle kaustaks python-flask-server
        • Edaspidi muudame python-flask-server kausta. Samuti olge ettevaatlik, et hiljem genereeritud koodiga te ei kirjutaks üle oma muudatusi.
  • OpenAPI generaatori kasutamine veebiteenusena - See on alternatiiv, kui probleemid java kasutamisega
    • See lahendus nõuab, et spetsifikatsioon oleks kätte saadav internetist.
      • Ladige spetsifikatsiooni fail veebiteenus.yaml üles mõnda platvormi, kus on võimalik seda kätte saada veebilinkgi kaudu. Näiteks dropbox, UT owncloud, github, vms. Tähtis on, et saaks OpenAPI veebiliidelese argumendiks anda veebi link selle faili sisule.
      • Kui kasutada UT owncloud'i, siis kopeerige faili alla tõmbamise link (Lael Alla nupp üleval paremal, kopeerige selle nupu/lingi aadress), MITTE selle jagamise link (Kuna see näitab veebilehte, mille kaudu on võimalik faili alla laadida)!!
    • Saatke POST päring OpenAPI veebiteenuse vastu:
      • PowerShell abil: Invoke-RestMethod -Uri "http://api.openapi-generator.tech/api/gen/servers/python-flask" -Method 'Post' -Body '{"options": {"packageName": "raamatu_teenus"},"openAPIUrl": "FAILI_ASUKOHA_VEEBI_LINK"}' -ContentType "application/json"
        • asendage FAILI_ASUKOHA_VEEBI_LINK korrektse lingiga teie faili asukohale veebis.
      • curl abil:
        curl -H "Content-type: application/json" \
            -X POST \
            -d '{"options": {"packageName": "raamatu_teenus"},"openAPIUrl": "FAILI_ASUKOHA_VEEBI_LINK"}' \
             http://api.openapi-generator.tech/api/gen/servers/python-flask
        • asendage FAILI_ASUKOHA_VEEBI_LINK korrektse lingiga teie faili asukohale veebis.
    • Tulemusena tagastatakse teile veebiaadress, mille kaudu saab genereeritud koodi repositooriumi alla laadida. Tehke seda. Näiteks, browseris selle aadressi avamise tulemusena tõmmatakse seef ail alla.
    • NB! Hoolitsege, et Powershell aken ei oleks liiga väike, muidu võib see näidata ainult osa lingist.
    • Pakkige alla laetud repositoorium lahti ning kopeerige see kausa python-flask-server
      • Edaspidi muudame python-flask-server kausta. Samuti olge ettevaatlik, et hiljem genereeritud koodiga te ei kirjutaks üle oma muudatusi.
  • Uurige genereeritud projekti sisu kaustas python-flask-server
  • See sisaldab:
    • openapi_server kausta, kus on serveri implementatioon
    • Docker faili, mille abil saab lihtsalt rakenduse üles seada Dockeris
    • requirements.txt faili, kus on kirjas mis Python teegid on vaja installeerida, et serverit jooksutada
    • controllers/default_kontroller.py faili, kus on kõik API meetodid, mida meil on vaja hiljem modifitseerida. Selles praktikumis on see ainuke koodi fail, mida me muudame.

Ülesanne 5.3: Loodud API testimine

Selles ülesandes instaleerime loodud API serveri python programmina, käivitame ning testime seda. Genereeritud serveris on lisaks veebiteenusele ka veebipõhine kasutajaliides, mis lihtsustab loodud veebiteenuse testimist ning töötab interaktiivse dokumentatsioonina.

Serveri rakendust saab installeerida kas Python rakendusena Python virtuaalses keskkonas (Virtual environment) või Dokeri konteineri ehitamise kaudu. Selles praktikumis kasutame esimest võimalus, aga kui soovite abi Dockeri kasutamisega, siis võtke ühendust praktikumi juhendajaga (vaja on muuta requirements.txt ning Dockerfile faile, et see tööle saada).

  • requirements.txt muutmine. Selle sisu ei ole vaja muuta, aga kui hiljem tekib probleeme teekide installeerimisega, siis kontrollige, et installeerite need tühja Python Virtuaalkeskkonna sees.
    • Kui tekib probleeme nende teekide installeerimisega teie arvutis, siis kindalsti võtke ühendust praktikumi juhendajaga
  • Python virtual environment üles seadmine ja käivitamine
    • Avage käsurida (cmd windowsis)
    • Liikuge käsureal genereeritud serveri kausta python-flask-server
    • Loome Python virtuaalse keskkonna kausta myenv:
      • python -m venv myenv
    • Aktiveerime Python virtuaalse myenv keskkonna
      • Windowsis: .\myenv\Scripts\activate.bat
      • Linuksis: source ./myenv/bin/activate
      • NB! Tlevikus, kui soovite programmi uuesti kävitada, aga olete vahepeal käsurea kinni pandud, siis tuleb uuesti aktiveerida Pythoni virtuaalne keskkond!
  • Python teekide installeerimine
    • pip install -r requirements.txt
  • Rakenduse käivitamine
    • python -m raamatu_teenus
  • Veebiteenuse GUI veebiliidesena on kätte saadav aadressil: http://localhost:8080/ui
    • Proovige läbi kõik meetodid.
    • tehke iga meetodi proovimise ja saadud vastuse kohta üks ekraanivaade (kokku 4).

Ülesanne 5.4: Veebiteenuse OpenAPI spetsifikatsiooni täiendamine

Vaatame nüüd kuidas täiendada OpenAPI spetsifikatsiooni.

  • Lisage OpenAPI spetsifikatsiooni puuduva meetodi: (/raamatud/{bookId} GET)
    • Lisage uus get: plokk YAML ploki /raamatud/{bookId}: sees.
    • Looge järgnevad YAML võtmed/plokid:
      1. summary: - Siin on lihtsalt operatsiooni kirjeldus tekstina
      2. operationId: - Siin peaks olema Pythoni meetodi nimi, mis luuakse slle HTTP meetodi implementeerimiseks. Pange sama nimi, mis teil oli eelmise praktikumi vastava meetodi kood. Saate vaadata kuidas see on defineeritud teiste operatioonide juures.
      3. parameters: See peaks defineerima URI parameetri bookId, mida kasutatakse raamatu id edastamiseks operatsioonile URI kaudu. Vaadake näidet /raamatud/{bookId}: delete plokist. Aga muutke vähemalt selle kirjeldus (description:) ära.
      4. responses: - Siin peaks defineerima kõik selle meetodi tagastuskoodid ja vastuse (response) sõnumite sisu ja struktuuri:
        • 200 - Raamatu tagastamine õnnestus
          • Lisage description: - vastuse kirjeldus, ehk, et Raamatu tagastamine õnnestus
          • sisu tüüp (content) on text/plain:
            • Sisu struktuur (schema) on string, ehk type: string
        • 404 - Raamatut ei leitud
          • Selle meetodi vastuse sõnumi sisu (content) on tühi JSON dokument (application/json tüüpi, {} väärtus)

Testime nüüd loodud spetsifikatsiooni ära.

  • Genereerige uuesti Veebiteenuse kood
    • Kui tekib error koodi genereerimisel, võib see olla tekkinud selle tõttu, et YAML dokument on vigase struktuuriga.
      • Kasutage järgnevat veebirakendust, et uurida kas YAML fail on korrektse struktuuriga: https://onlineyamltools.com/validate-yaml
    • NB! kontrollige, et failidest, mida olete vahepeal muutnud, on tehtud koopiad!
    • Kopeerige genereeritud kausta sisu kausta python-flask-server.
    • Pange sever uuesti tööle
      • Ei ole vaja Python teeke uuesti installeerida.
    • Testige nüüd veebiliidese kaudu, et uus (/raamatud/{bookId} GET) meetod on lisatud, ning saame seda välja kutsuda, ilma veateadeteta.
      • Kui see ei tööta, siis kontrollige spetsifikatsioon üle, tehke vajalikud muudatused, et seda parandada, genereerige kood uuesti ning testige uuesti.
      • NB! Kui te ei leia, mis võib valesti olla, siis küsige praktikumi juhendaja käest abi.

Ülesanne 5.5: Veebiteenuse implementeerimine

Implementeerime nüüd genereeritud veebiteenuse meetodite sisu. Saame Väga suures mahus ära kasutada koodi, mille te kirjutasite Praktikumis 4, aga tuleb teha mõned muudatused.

  • Lisage import käsud (kopeerides need eelmise praktikumi lahendusest) järgnevate Python teekide jaoks
    • requests
    • os
    • send_file
  • Raamatute kausta seadistamine
    • Saame luua raamatute kausta sama moodi nagu eelmise praktikumi lahenduses.
    • NB! Aga raamatute kausta asukoha PEAB seadistama täis-teena arvutis, kuna seda kausta proovitakse programmist käivitada erinevatest alamkaustadest.
    • Looge default_controller.py failis muutuja raamatute_kaust
      • Näide kuidas seda seadistada Windowsis: raamatute_kaust = "C:\\Users\\jakovits\\raamatud"
        • Kaust peab olema teie kasutaja õigustega, ehk pange see oma kodukausta sisse.
  • GET meetodite implementeerimine:
    • raamatu_allatombamine(book_id)
      • Peaks piisama, kui kopeerida eelmise praktikumi sellele operatioonile vastava meetodi sisemine kood
    • raamatu_nimekiri()
      • Peaks piisama, kui kopeerida eelmise praktikumi sellele operatioonile vastava meetodi sisemine kood
  • DELETE meetodi implementeerimine
    • Meetod: raamatu_kustutamine(book_id)
    • Peaks piisama, kui kopeerida eelmise praktikumi meetodi sisemine kood.
  • POST meetodite implementeerimine:
    • POST operatiooni kaudu saadetud JSON sisendi töötlus toimub teismoodi. Meie kood ei töötle enam JSON objekti otse, vaid selle asemel on loodud eraldi Python klass (Flask Model).
    • raamatu_lisamine(raamatu_loomise_sisend=None)
      • Meetodisse peaks alles järma koodiread:
            if connexion.request.is_json:
                raamatu_loomise_sisend = RaamatuLoomiseSisend.from_dict(connexion.request.get_json())  # noqa: E501
      • Raamatu ID väärtuse saab lugeda raamatu_loomise_sisend objekti (RaamatuLoomiseSisendmudeli klassi objekt, mis representeerib selle POST meetodi sisendobjekti) seest nii:
        • raamatu_id = raamatu_loomise_sisend.raamatu_id
      • Eemaldage kood (kui seda kasutasite), mis kontrollib kas raamatu_id on number. Nüüd kontrollitakse seda genereeritud Flask serveri koodi poolt automaatselt.
      • Ülejäänud koodi peaks saama üle võtta eelmise praktikumi vastavast meetodist. Ehk saab kopeerida koodi, mis jääb peale raamatu_id muutuja väärtustamist.
    • raamatust_sone_otsimine(raamatu_otsingu_sisend=None)
      • Meetodisse peaks alles järma koodiread:
            if connexion.request.is_json:
                raamatu_otsingu_sisend = RaamatuOtsinguSisend.from_dict(connexion.request.get_json())  # noqa: E501
      • Raamatu ID ja otsitava sõne väärtused saab lugeda raamatu_otsingu_sisend objekti (RaamatuOtsinguSisend mudeli klassi objekt, mis representeerib selle POST meetodi sisendobjekti) seest nii:
        •     sone = raamatu_otsingu_sisend.sone
              raamatu_id =  raamatu_otsingu_sisend.raamatu_id
      • Eemaldage kood (kui seda kasutasite), mis kontrollib kas raamatu_id on number. Nüüd kontrollitakse seda genereeritud Flask serveri koodi poolt automaatselt.
      • Ülejäänud koodi peaks saama üle võtta eelmise praktikumi vastavast meetodist. Ehk saab kopeerida koodi, mis jääb peale sone ja raamatu_id muutujate väärtustamist.
Implementeeritud veebiteenuste testimine
  • Käivitage serveri rakendus uuesti. Iga muudatuse järel tuleb seda uuesti käivitada.
  • Python koodiga seotud veateated ilmuvad serveri käivitamise väljundisse!
  • Veebiteenuse veebiliides on kätte saadav aadressil: http://localhost:8080/ui
    • Proovige läbi kõik meetodid.
    • tehke iga meetodi proovimise ja saadud vastuse kohta üks ekraanivaade (kokku 5).

Lahenduse esitamine

Praktikumi lahendusena tuleb esitada:

  1. veebiteenus.yaml fail
  2. Ekraanivaated ülesannetest 5.3 ja 5.5 (4+5 ekraanivaadet)
  3. Genereeritud programmi kaust zip failina
    • NB! Ei tohi kaasa panna myenv kausta!!
  4. Failid tuleks kokku pakkida üheks suuremaks Zip failiks enne üles laadimist.
You must be logged in and registered to the course in order to submit solutions.

Võimalikud probleemid ja nende potentiaalsed lahendused.

  • Kui aate veateate Pythoni teekide kohta käsu pip3 install -r requirements.txt jooksutamisel, siis proovige uuendada Python pip teeki.
    • Veateate näide: ERROR: Double requirement given: connexion[swagger-ui]<=2.14.2 (from -r requirements.txt (line 5)) (already in connexion[swagger-ui]>=2.6.0 (from -r requirements.txt (line 1)), name='connexion')
    • Lahendus:
      • python -m pip install --upgrade pip
  • Kui programmi jooksutamine ei tööta, siis kontrollige, et olete aktiveerinud Python'i virtuaalse keskkonna!
  • Institute of Computer Science
  • Faculty of Science and Technology
  • University of Tartu
In case of technical problems or questions write to:

Contact the course organizers with the organizational and course content questions.
The proprietary copyrights of educational materials belong to the University of Tartu. The use of educational materials is permitted for the purposes and under the conditions provided for in the copyright law for the free use of a work. When using educational materials, the user is obligated to give credit to the author of the educational materials.
The use of educational materials for other purposes is allowed only with the prior written consent of the University of Tartu.
Terms of use for the Courses environment