I del C av prosjektet skal dere implementere en REST API for en smarthus sky-tjeneste ved bruk av rammeverket FastAPI.
Start-koden for prosjektet finnes i dette GitHub repository:
https://github.com/selabhvl/ing301-projectpartC-startcode.git
Igjen forutsettes at dere har implementert en fullstendig løsning til forrige oppgaven (del B). Enten kan dere bygge direkte på deres eksisterende løsning eller dere begynner med et helt fersk repository ved å klone startkoden for første delen igjen også kopiere filene til henholdsvis løsningsforslagene A og B inn for å ha et utgangspunkt til denne oppgaven.
Dere kopierer inn filene fra dette repository'et ("Download as ZIP") inn i det eksisterende prosjekt slik at mappestrukturen skal se noenlunde slik ut:
.
├── data
│ └── db.sql
├── README.md <-- erstatt hvis du vil
├── smarthouse
│ ├── __init__.py
│ ├── api.py <-- nytt
│ ├── domain.py
│ └── persistence.py
├── tests
│ ├── __init__.py
│ ├── bruno <-- nytt
│ │ └── ...
│ ├── demo_house.py
│ ├── test_part_a.py
│ └── test_part_b.py
└── www <-- nytt
└── ...
Selv om det er mulig (og at dette vil være en veldig lærrik oppgave) å implementere en HTTP-server helt fra bunn av,
så ville dette være veldig tidkrevende også. Vi skal derfor bruke en bibliotek som heter FastAPI.
FastAPI er ikke en del Python sin standard bibliotek og må derfor installeres som en Python Packages.
Installasjon av packages kan være en utfordring siden man må manøvrere ting som Externally Managed Environments, "package managers" som pip
, conda
, poetry
osv...
Dette kan være utfordrende i starten!
En god praksis er å lage noe som kalles en virtual environment for hver Python prosjekt. Dette gjør at man kan styre hvilken Python-fortolker som skal brukes og for å kunne holde paketer adskilt.
For å oprette en slik virtual environment åpner du et nytt terminalvindu og så beveger du deg inn i prosjektmappen. Her utfører du følgende kommando:
py -m venv .venv
hvis du bruker Windows, eller
python3 -m venv .venv
hvis du bruker Linux/UNIX/MacOS.
Vær også obs på at under noen operativsystemer må venv
-modulen installeres for første gang gjennom operativsystemets pakkeforvaltning, f.eks.
under Ubuntu må du utføre:
sudo apt-get install python3-venv
Etter at det virtuelle Python miljøet er blitt opprettet må det aktiveres med
.venv\Scripts\activate
under Windows, eller
source .venv/bin/activate
under Linux/UNIX/MacOS.
Du vil nå se at ledeteksten i konsollen har forandret seg litt og hvis du nå sjekker hvilke python
og pip
er som aktive:
Windows:
where python
where pip
Linux/UNIX/MacOS
which python
which pip
Da vil du se at disse nå peker mot den .venv
-mappen som ble opprettet før.
Nå at det virtuelle Python miljø er på plass er det lurt å sjekke om pip
der og oppdatert:
python -m pip install --upgrade pip
Istedenfor python -m pip
burde du også kunne skrive bare pip
.
Hvis du får en feilmelding at modulen pip
kan ikke finnes så må du eventuelt sjekke om denne pakken må installeres
gjennom operativsystemets forvaltningssystem (noe som heter python3-pip
).
Når pip
er på plass kan FastAPI samt avhengigheter installeres ved å kjøre følgende kommandoer:
python -m pip install fastapi
python -m pip install "uvicorn[standard]"
Nå skulle alt være på plass for å kunne kjøre applikasjonen:
python -m uvicorn smarthouse.api:app --reload
når konsollen viser noe slik:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
så er web applikasjonen klart! Du kan åpner nettleseren på
for å se en liten demoside og
vil gi deg en oversikt over REST ressursene som finnes.
Hvis du ikke allerede har gjort det, så er det nå en god tidspunkt å laste ned Bruno,
starte det, lage en ny "collection" og prøve å sende en HTTP GET request til http:127.0.0.1:8000/hello
.
Gratulerer! Da er Setup avsluttet og du er klar til å begynne med oppgaven!
Enn så lenge du holder konsollen åpen så vil være web-tjeneren være aktivt. I tillegg vil den automatisk reagere på alle endringer i koden og automatisk oppdatere seg slik at du får en nesten sømløs opplevelse. Når du vil likevel avslutte applikasjonen må du sette fokus på terminalvinduet også trykker du Ctrl + C samtidig, da kommer du tilbake til ledeteksten.
Hvis du vil gå ut av det virtuelle Python miljøet (f.eks. for å jobbe med et annen Python projsket) kan du kalle:
deactivate
For å komme inn i det virtuelle miljøet igjen gjør du akkurat likt som beskrevet ovenfor ved å kalle activate
.
Husk at dette også må gjøres når du starter PCen din på nytt eller du åpner et nytt terminalvindu.
I tillegg vil du kanskje også at din editor eller IDE samarbeider med det virtuelle miljøet.
Sjekk dokumentasjonen til VS Code eller PyCharm.
I de fleste tilfellene vil disse automatisk oppdager at det finnes en venv
i ditt prosjekt og forholder seg tilsvarende.
Som nevnt består altså oppgaven i det å lage en REST API for smarthuset. Konkret skal dere opprette følgende endepunkter:
Det skal finnes endepunkter får inspisere strukturen til huset:
GET smarthouse/
- information on the smart houseGET smarthouse/floor
- information on all floorsGET smarthouse/floor/{fid}
- information about a floor given byfid
GET smarthouse/floor/{fid}/room
- information about all rooms on a given floorfid
GET smarthouse/floor/{fid}/room/{rid}
- information about a specific roomrid
on a given floorfid
Det skal finnes endepunkter for tilgang til enheter:
GET smarthouse/device
- information on all devicesGET smarthouse/device/{uuid}
- information for a given device identfied byuuid
Det skal finnes spesielle endepunkter for tilgang til sensor funksjoner:
GET smarthouse/sensor/{uuid}/current
- get current sensor measurement for sensoruuid
POST smarthouse/sensor/{uuid}/current
- add measurement for sensoruuid
GET smarthouse/sensor/{uuid}/values?limit=n
- getn
latest available measurements for sensoruuid
. If query parameter not present, then all available measurements.DELETE smarthouse/sensor/{uuid}/oldest
- delete oldest measurements for sensoruuid
Det skal finnes spesielle endepunkter for tilgang til aktuator funskjoner:
GET smarthouse/actuator/{uuid}/current
- get current state for actuatoruuid
PUT smarthouse/device/{uuid}
- update current state for actuatoruuid
For de fleste av endepunktenes funksjonalitet kan en mye av funksjonene i SmartHouse
-klassen sannsynligvis gjenbrukes.
For noen må kanskje nytt funksjonalitet utvikles (husk også database tilkoblingen).
Husk også at data som returneres fra endepunktet eller sendes til endepunktet skal være i JSON-formatet.
FastAPI er i stand til å automatisk overføre Python objekter til JSON i noen tilfelle:
- strenger (
str
), - tall (
int
,float
), - sannhetsverdier (
bool
), None
-verdien,- lister og ordbøker med streng-nøkler som igjen inneholder lister, ordbøker eller verdiene nevnt ovenfor.
Alternativt kan du også bruke Pydantic-biblioteket (den kommer automatisk med når man installerer FastAPI) for å oversette dine egne klasser automatisk.
Viktig er at dere på forhånd tar en avgjørelse om hvordan inn- og utdata for hver endepunkt skal være strukturert.
En del av oppgaven er å teste deres endepunkter.
For dette anbefaler vi Bruno-verktøyet som gjør det mulig å lage en Collection av test-request og sjekker disse inn i git.
Dette startkode repository inneholder en slik påbegynt "Test-Suite" som ligger under tests/bruno
.
Du kan åpne denne samlingen ved å trykke "Open Collection" når du starter Bruno og så navigerer du den nevnte mappen i din filsystem.
Her er det også demonstrert hvordan du kan bruker variable og hvordan man skrive tests i Bruno ved brul av assertions (forventninger).
For å løse oppgaven kan det være en god idé å søke inspirasjon i eksemplet fra forelesningen i uke 12 der FastAPI ble brukt til å utvikle en REST API for sykkelcomputer eksemplet:
Koden finnes her:
https://github.com/selabhvl/ing301public/tree/main/examples/12_restapi_webservices
Der er også hjelp å hente i dokumentasjonen for FastAPI som finnes via: