I del C av prosjektet skal dere implementere en nettverksapplikasjon bestående av fire deler:
- Et REST API for en smarthus sky-tjeneste ved bruk av rammeverket FastAPI
- En klient-applikasjon som representerer en temperatursensor som rapporterer målinger til sky-tjenesten
- En klient-applikasjon som representerer en lyspære som endrer tilstand (av/på) basert tilstand satt i sky-tjenesten
- En klient-applikasjon som gjør det mulig å hente målinger fra temperatursensoreren og sette tilstanden på lyspæren baser via sky-tjenesten.
Samlet betyr det at en en bruker via sky-tjenesten kan få informasjon om temperaturen i huset og kan kontrollere lyspæren.
Klient-applikasjonen skal basere seg på requests-biblioteket for å implementere bruk av REST API'et.
Figuren nedenfor viser illustrerer den nettverksapplikasjon som dere skal ende opp med.
Start-koden for prosjektet er organisert på tilsvarende måte som de tidligere deler av prosjektet og inneholder løsningsforslaget fra del A.
.
├── README.md
├── clients
├── __init__.py
│ ├── actuatorclient.py <-- nytt: her skal lyspære-klienten implementeres
│ ├── app.py <-- nytt: her skal bruker-klienten implementeres
├── common.py <-- nytt: her er klasse for utveksling a målinger/tilstander implementert
│ └── sensorclient.py <-- nytt: her skal temperaturmåler-klienten implementeres
├── smarthouse
│ ├── __init__.py
│ ├── api.py <-- nytt: her skal REST API (sky-tjenesten) for smarthuset implementeres
│ ├── domain.py
│ └── dto.py <-- nytt: klasser for dataoverføring mellom klienter og sky-tjenesten
├── tests
│ ├── __init__.py
│ ├── bruno <-- nytt: Bruno samling av forespørseler for testing av REST API
│ │ └── ...
│ ├── demo_house.py
│ └── test_part_a.py
└── www <-- nytt: en liten webside for å teste REST API'et
└── ...
For å forenkle del C av prosjektet skal vi ikke bruke koden for persistens i database fra del B. De som ønsker kan kopiere egen løsning fra del A og eventuelt også integrere database-delen.
Start med å klone dette start-kode repository på samme måten som tidligere ved å bruke "Use as Template" funksjonaliteten på GitHub og så klone ned til din lokale maskin.
[VIKTIGT] Dette prosjektet forutsetter at du bruker Python versjon 3.12 eller nyere. Hvis
python -Vviser et tall lavere enn3.12.0så må du først installere den nyeste Python versjonen og legger den på dinPATH.
For implementasjon av nettverksapplikasjonen skal vi bruke HTTP-protokollen for kommunikasjon mellom klient-applikasjonene og sky-tjenesten og bygge på to biblioteketer:
- FastAPI for å implementere REST API for sky-tjenesten (server-siden)
- Requests for å implementere REST API klienter (klient-siden)
Ingen av disse modulene/pakkene er del Python sin standard bibliotek og må derfor installeres som Python Packages.
Installasjon av packages kan være en utfordring siden en må manøvrere ting som Externally Managed Environments og package managers som pip, conda, poetry. Dette kan være utfordrende i starten!
Det er god praksis å lage et virtual environment for hvert Python prosjekt. Dette gjør at en kan styre hvilken Python-fortolker som skal brukes og holde installerte pakker adskilt mellom ulike prosjekt.
For de som bruker PyCharm eller VSCode kan et virtuelt Python miljø etableres via grensesnittet når et prosjekt for koden opprettes.
Alternativt kan et virtual environment opprettes ved å åpne et nytt terminalvindu og så bevege seg inn i prosjektmappen.
Her utfører du følgende kommando:
python -m venv .venvhvis du bruker Windows, eller
python3 -m venv .venvhvis du bruker Linux/UNIX/MacOS.
Hvis du får en melding som module 'venv' not found så må du installere den først i din system interpreter med:
python -m pip install venvVær obs på at under noen operativsystemer/installasjoner der
Python fortolkeren forvaltes av operativsystemet eller tilsvarende pakkeforvaltning,
så må venv-modulen installeres gjennom operativsystemets pakkeforvaltning, f.eks.
sudo apt-get install python3-venv # Debian/Ubuntu
brew install virtualenv # brukere av Homebrew under MacOS
choco install python3-virtualenv # brukere av Chocolatey under WindowsEtter at det virtuelle Python miljøet er blitt opprettet må det aktiveres med
.venv\Scripts\Activate.ps1under Windows (vi antar at du bruker PowerShell), eller
source .venv/bin/activateunder 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:
Get-Command python
Get-Command pipLinux/UNIX/MacOS
which python
which pipDa vil du se at disse nå peker mot den .venv-mappen som ble opprettet før.
Nå det virtuelle Python miljø er på plass er det lurt å sjekke om pip der og oppdatert:
pip install --upgrade pipNår pip er på plass kan FastAPI samt requests installeres ved å kjøre følgende kommandoer:
pip install "fastapi[standard]"
pip install requests
Nå skulle alt være på plass for å kunne start sky-tjeneste applikasjonen:
fastapi dev smarthouse/api.pyNå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 REST API sky-tjenesten klar! Du kan åpner nettleseren på
for å se en liten demoside og
vil gi deg en oversikt over REST endepunktene som finnes.
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:
deactivateFor å 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.
Hvis du ikke allerede har gjort det, så last ned Bruno,
start det, lag en ny "collection" og prøv å sende en HTTP GET request til http:127.0.0.1:8000/hello.
For å løse oppgaven kan det være en god idé å se tilbake på forelesningen der FastAPI ble brukt til å utvikle et REST API for sykkelcomputer eksemplet. Det er også hjelp å hente i dokumentasjonen for FastAPI som finnes via: https://fastapi.tiangolo.com
REST API sky-tjenesten for smarthuset skal implementeres i smarthouse/api.py og bestå av endepunktene (tjeneste) som beskrevet nedenfor.
Der skal implementeres endepunkter for å få informasjon om strukturen til smarthuset:
GET smarthouse/- information on the smart houseGET smarthouse/floor- information on all floorsGET smarthouse/floor/{fid}- information about a floor given byfidGET smarthouse/floor/{fid}/room- information about all rooms on a given floorfidGET smarthouse/floor/{fid}/room/{rid}- information about a specific roomridon a given floorfidGET smarthouse/device- information on all devicesGET smarthouse/device/{uuid}- information for a given actuator identfied byuuid
Der skal implementeres endepunkter for tilgang til sensor-ressurser:
GET smarthouse/sensor/{uuid}- information for a given sensor identfied byuuidGET smarthouse/sensor/{uuid}/current- get current sensor measurement for sensoruuidPUT smarthouse/sensor/{uuid}/current- update measurement for sensoruuidDELETE smarthouse/sensor/{uuid}/current- delete current measurements for sensoruuid
Der skal implementeres endepunkter for tilgang til aktuator-ressurser:
GET smarthouse/actuator/{uuid}/state- get current state for actuatoruuidPUT smarthouse/actuator/{uuid}/state- update current state for actuatoruuid
Informasjon om ressurser 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 tilfelle av innebygde Python verdier:
- 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.
Når du har definert din egen klasse må du i utgangspunktet skrive din egen serialiserings-mekanisme til/fra JSON format.
Men en kan også bruke Pydantic-biblioteket (den kommer automatisk med når man installerer FastAPI)
for å oversette dine egne klasser automatisk. For å bruke Pydantic må du definere dine egne klasser som subklasser av BaseModel-klassen i Pydantic og da kan du bruke disse klassene i dine endepunkts-funksjoner for å automatisk få oversettelse til/fra JSON.
Filen smarthouse/dto.py inneholder starten på noen klasser basert på Pydantic som kan brukes som bindeled mellom implementasjon av REST API endepunktene i smarthouse/api.py som sender JSON til/fra sky-tjenesten og informasjonen om smarthuset som er lagret i objektene av SmartHouse-klassene i smarthouse/domain.py. Prinsippet er at klassene i smarthouse/dto.py brukes som data transfer objekter, slik at data for smarthuset som skal returneres fra et endepunkt hentes ut og lagres i et slikt objekt og at informasjon som sendes til smarthuset via et endepunkt blir oversatt til et slikt objekt før det brukes for å oppdatere informasjonen i smarthuset.
En del av oppgaven er å teste om endepunktene i REST API'et fungerer.
For dette finnes en Collection av test-request for smarthuset sky-tjenesten under tests/bruno.
Du kan åpne denne samlingen ved å trykke "Open Collection" når du starter Bruno på første gang eller hvis du allerede har lagt noen collections selv så trykker du på +-ikonet oppe til høyre og velger "Open Collection" derifra. Det åpner seg en filutforsker-vindu der du kan navigere til den nevnte mappen i filsystemet.
Kjør testene etterhvert som du implementerer endepunktene for å sjekke at de fungerer som forventet. De skal returnere informasjon svarende til det som er definert for demo smarthuset som legger under tests/demo_house.py.
I denne oppgaven skal der implementeres klient-applikasjoner som gjør det mulig for :
- aktuatorer å hente deres tilstand fra sky-tjenesten og sette deres tilstand i henhold til dette
- sensorer kan sende deres aktuelle målinger til sky-tjenesten
For å forenkle oppgaven skal det kun implementeres klient-applikasjoner for to enheter (devices) i demo smarthuset:
- Sensor: Temperatursensor (uuid=
4d8b1d62-7921-4917-9b70-bbd31f6e2e8e) - Actuator: Lyspære (LightBulb) (uuid=
6b1c5f6b-37f6-4e3d-9145-1cfbe2f1fc28)
Start-koden for disse to enheter finnes i filene actuatorclient.py og sensorclient.py i mappen clients. Filen common.py inneholder noen klasser som kan brukes for utveksling av informasjon mellom klient-applikasjonene og sky-tjenesten.
Test klient-applikasjonen ved å kjøre det samtidig som sky-tjenesten fra oppgave 5 og sjekk ved at bruke testenne i Bruno at temperaturen for temperatursensoren oppdateres i sky-tjenesten og at tilstanden for lyspæren hentes ned og settes korrekt også når den tilstanden endres ved å sende en request til sky-tjenesten fra Bruno.
I denne oppgaven skal der implementeres en bruker-applikasjon som gjør det mulig for en bruker å seneste måling fra temperwaturesensorer og sette tilstanden på lyspæren via sky-tjenesten.
Startkoden for bruker-applikasjonen finnes i filen app.py i mappen clients. Her kan det også være nyttig å bruke klassene i common.py for å utveksle informasjon mellom bruker-applikasjonen og sky-tjenesten.
Test til slutt hele system ved å starte sky-tjenesten, de to klient applikasjoner for enhetene og slutt-bruker applikasjonen. Se at den aktuelle temperatur kan hentes fra sky-tjenesten og at bruker-applikasjonen kan anvendes til å slå lyspæren av og på.
