Hej på er. Som utlovat så tänkte jag gå igenom ett enklare demo där vi sätter upp Python med Flask mot en MySQL-databas som i vårt fall är Northwind. Svårt att hitta kopplingar från den här kursen mot Python som är ert primära...
programspråk som ni läser till. Men jag tänker att det här kanske är något steg i rätt riktning i alla fall. Så har vi det inspelat och ni får ta del av demot.
Nu ska vi se, vi måste först skapa en map då. Då kommer jag där uppe till Flask MySQL API Demo. Så går vi till den, öppnar upp den i Microsoft Studio Code. Och så behöver vi tänka på vad vi ska inkludera för paket. Och det vi behöver inkludera är de här fyra.
Det är python.env. Som hjälper oss med miljövariabler. Så att vi inte lägger dem direkt i Python-filen.
Och sen Flask givetvis. Och sen integreringen med Flask mot MySQL DB. Så vi får en sån integrering.
Och en MySQL-klient. Så vi installerar paketen. Sedan skapar jag en requirements txt.
Om jag nu kollar vad som ingår så ser vi att vi har en requirements txt. Jag öppnar upp den i Visual Studio Code. Så kan ni använda er av kommandot som är här för att installera de paketen utifrån den txt.
Det är lite svårt annars att veta vad för typ av paket som ska ingå. Vi kan börja med att sätta upp den här environment-filen. Den ska i sin tur innehålla fyra olika variabler som vi döper till med prefix db. Så kör vi snake casing. Så host, user.
password och name på databasen. Så det är egentligen det vi säger, alltså var någonstans vi vill peka på vilken koppling vi vill peka på. I vårt fall vill vi peka på en lokal koppling. Och så vill vi använda oss av ett lösnordet.
Och sen vill vi mata in lösnordet. Så ditt lösnord där. Och sen vilken databas.
Så det är ju viktigt att den heter rätt. Och det är ju den ni använder när ni är i er DBMS och skriver. Use Northwind eller Use LibraryDB.
Och sen behöver vi givetvis sätta upp någon form av Python-fil. Vi kan döpa till api.py. Vi ska importera lite saker. OS, JSON.
För det är det vi vill leverera ut. Från databasen till vårt API. Här säger vi att vi vill använda oss av miljövariabeln som vi satte upp i det tidigare steget.
Sedan vill vi också använda oss av flask och lyfta in lite saker. Relevanta saker för vårt rest API. MySQL. Sedan vill vi hämta...
Bursers för att vi ska kunna skriva queries. Och så sätter vi upp appen som en flask. Och så laddar vi in saker i det här kontextet från vår environment-fil.
App.config. Där behöver vi säga isqlhost på den första. Och sen behöver vi säga user, password och databas. Och där refererar vi till den här delen.
Och så ska vi hämta. våra miljövariabler. Här hade vi kunnat lagt in saker och ting statiskt.
Localhost exempelvis. Host är host på första raden. User är user på andra raden. password är password och sen är det name. Och sen är det en instans av mysql där vi lyfter in app.
Sen behöver vi börja sätta upp våra routes. Och det gör vi genom att... Säga att vi vill ha en route. Vart vi ska gå mot.
Alltså i det här fallet så sätter vi upp en route för root. Vi kan lägga till en point för products eller vad det nu skulle kunna vara. Men i det här fallet så kör vi bara en route.
Methods. Hur man ska komma åt den. ROOT API då.
För att jag tycker det är lite tråkigt om inte vi visar någonting vettigt för slutanvändaren. Eller er i det här fallet. Genom att vi sätter upp en funktion.
Som tillåter oss att titta på någon form av specifikation för vad grejerna ska ingå. Load API docs finns ju inte. Den funktionen behöver vi sätta upp.
Vi vill öppna en fil. Så via instanseringen av OS så kan vi peka på en sökväg. Root path. Och så joinar vi ihop.
mot den med vad våra dokument heter. Och retonerar det. API docs.json finns inte i det här fallet. Det behöver vi lyfta in. Och så ska jag lyfta in rätt environment-variabler också.
Men jag vill inte att ni ska se det. Och så lyfts in API dock. Det vi tittar på just nu är JSON. En beskrivande JSON för vad vårt rest API innehåller. Alternativt hade ni kunnat sätta upp en swagger eller så.
Men det är inte av skopet av det här demot. Det betyder att när vi går till... url och den push som den här kör på så kommer vi om vi går till root kunna se den här jason i webblassaren. Vi har inte gått mot databasen än men det tänker jag att vi ska göra nu.
Så vi kan väl saxa den här delen, app.route, men istället säga products. För det är ju, vet du vad Northwind-databasen innehåller. Den har ju som sagt en del olika tabeller som kan vara relevanta. I vårt fall så håller vi oss enkelt med att ha en tabell.
Enkelt. Och går mot. Product.
I det fallet. Jag döper endpointen till plural. Men det är den tabellen som.
Vi kommer att göra. De olika kruddgrejerna mot. Via vårt rest API.
Då kan vi hämta saker och ting från databasen. Via API. Så man agerar som middleman.
Så om vi går mot product. Så vill vi ha en get och i den så vill vi sätta upp en funktion. Och så säger vi att vi vill använda en connection mot vår databas. MySQL DB Cursors. Och den ska exekvera.
Select. Stjärna, from, product. Vi hämtar alla kolumner från produkttabellen. Och för att kunna stora vårt resultat i en variabel så sätter vi upp en products. Och så säger vi cursor, fetch all.
Jag tror inte att det är stor. Fetch all. Precis.
Inte camel casing. Fetch all. Och den returnerar JSON.
Därav JSONify. Kommer från flask. Vi får ganska mycket därifrån. Products.
Sen så kan vi testa att köra den här. Om den går mot main thread. Då drar vi debug.
Eller det kan vara true. Det kan vara bra om jag använder rätt logiska operator också. Och så säger vi p, api.py.
Då servar den vår flaskapp. Och ni får lite information här i konsolen. Vi ser att den körs på http vår lokala miljö.
Port 5000 som den exponerar ut. Här märker ni att det är det jag gör här. Jag går till root endpointen och då hämtar den mitt dokument där jag beskriver API via den här funktionen.
Det är egentligen det vi tittar på här. Om jag skulle trycka på products här, för det är en länk i det fallet. Om jag kan gå till den delen där.
Så kommer jag att få ut allting från föraktstabellen. Så kopplingen fungerar. Det är fantastiskt. Men vi gör inte så mycket mer än att bara tillåta hämtning här.
Jag tänker att vi ska kunna göra lite mer saker. I vårt demo. Vad sägs om att kanske hämta en specifik produkt? Då vill vi saxa den där delen igen. Och så vill vi säga products.
Och sen vill vi säga in product ID. Så det är som en placeholder. För vet du vad endpointen kommer innehålla.
Den förväntar sig givetvis en produktid som är numeriskt värd. 1, 3, 4 och så vidare. Def get product.
Och den ska ju givetvis ta in ett productid. Det är ju där vi kan hämta ut en specifik produkt. Cursor.
Kopierar det därifrån. Och sen säger vi cursor.execute. Och sen ska vi skriva lite SQL.
From product. Med litet p. Viktigt att vara noggrant här.
Where product id är lika med. Och sen använder vi procent s. Som är ett dynamiskt värde. Och hjälper till att motverka SQL-injektioner.
Så här säger vi ju att vi vill... Hämta alla kolumner från tabellen produkt. Där produktid är någonting. Och det är ju givetvis det som vi skickar in i vår funktion. Men vi har inte avslutat den riktigt än.
För vi måste ju säga vad det ska vara då. Och det ska ju vara från argumentet. Ni såg att den highlightades när vi get product funktionen. Och så säger vi product cursor. Inte fetch all i det här fallet.
Utan fetch one. Vi ska se om den dokumentationen finns här. Jo, här har vi den. Fetch many och fetch one.
Så då hämtar den en single sequence. Och det är det vi är intresserade av. För vi förväntar oss en produkt.
Om den finns, alltså att den innehåller någonting. Retunerar den. Jsonify. Annars fortfarande Jsonify.
Men nu vill vi säga error. Product not found. En statuskod.
Det här är en HTTP-statuskod. Så 404 står för not found. 400 står för Bad request eller 401 står för Unauthorized om jag inte missminner mig. Så det finns olika statuskoder som man ska använda sig av. Då kan vi köra igång den igen och testa om det funkar.
API.py Och sen sträckte jag till internal server error. Mm, då får vi något fel. Och det är för att vi ska stänga ner det här och kolla vad det är för fel.
Product int productID. Godakt, Cursor Fetch 1. Okej, jag behöver komma i den delen för annars kan den inte parsa rätt till en integer. Jag har stött på det här problemet förut och minns inte exakt varför.
Men den försöker göra om parametern till det icke nummeriskt värda i det fallet. Jag får lägga upp det på min to do. Men jag tänker att vi fortsätter i alla fall. Ni har ju demot sen i slutändan ändå.
Nu kan vi hämta alla produkter. Om vi kan hämta en specifik produkt. Men vi kan inte göra någonting annat som att lägga till en produkt eller uppdatera en produkt. Så det tänker jag att vi ska göra. Vi kan ju bättre separera lite grann med att säga till exempel att Load description of API.
API to fetch all products. Som jag la på fel ställe givetvis. Här är API-routen.
API to fetch all products. API endpoint to fetch product by product ID. Då ska vi se om vi tar den här delen.
Jag tänker att vi nu ska sätta upp möjligheten att skapa en ny produkt. API endpoint to add a new product. Laptop route products vill vi fortfarande använda men nu vill vi göra en post. Vi stökar inte på samma endpoint för vi säger att det ska vara en annan metod.
När vi är inne i webbläsaren och matar in adressen till vårt API så gör vi ju en get. Men om vi ska posta någonting så behöver vi använda oss av postman eller ha ett gränssnitt att gå emot där vi kan skicka data. Men för att vi ens ska kunna gå och skicka data så behöver vi sätta upp backend för det. Och det är precis det vi gör.
Vi vill lägga till produkt. Data ska vara det som kommer ifrån requestet. Det vill säga att det ska vara JSON-data. Nu behöver vi tänka vad innehåller produkttabellen.
Use Northwind. Describe product. Vår premiärnyckel är auto-inkrementerad, så den behöver vi inte bry oss om. För den kommer auto-generera det givetvis.
Product name, supplier ID, category ID. Quantity per unit, unit price, unit in stock kan vara relevant. De andra grejerna kan vi väl låta vara, för de är ju nullable.
Det ser vi här. Det är viktigt att tänka på. Så att de grejerna när man kommer skapa en produkt så kommer den då att bli 0. Så då kommer inte det ingå.
Product name. Så har vi data.get product name. Och så behöver vi lägga till lite fler kolumner.
Supplier ID exempelvis. Så har vi supplier ID. Och sen har vi category ID. Category ID. Och sen efterföljande kolumn är quantity per unit.
Quantity per unit. Och sen har vi unit price som är en relevant kolumn. Unit in stock.
Data.get. Unit in stock. Units on order. Reorder level. Discontinued.
Vi låter dem vara null. Sen ska vi sätta upp en cursor. Och sen vill vi.
Execute, vilket betyder att vi nu kommer att lägga till en ny post i vår tabell. Den delen är precis det som vi är vana med när det gäller... Vad heter det?
När det gäller... med values så behöver vi säga vad för någonting är det vi vill lyfta in till vad för tabell. Specificerar vi kolumner som ska ingå. Och sen så har vi det här dynamiska värdet eller placeholder. 1, 2, 3, 4, 5, 6 som vi ersätter med.
Det vi har satt upp här uppe. Supply-radikategoradik. Quantity per unit.
Unit price. Och sen unit in stock. Unit in stock.
Jag hade skrivit det i plural. Det var fel. Där behöver jag ändra det till unit in stock. Så.
Och sen behöver vi. Säger att vi ska lägga till det i databasen. MySQL connection commit. Vilket betyder att den kommer att exekvera det. Och sen så säger vi JSONify. Message.
Product added successfully. Och så returnerar vi en statuskod. Och då tänker jag att 201 blir bra. Står för no content. Men positivt sådant.
Vi förväntades inte. Något data tillbaka. Vi ville lägga till data.
Statuskoden 201 indikerar på att det gick bra. I det fallet. Och sen så kan vi lägga till en put.
Och en delete. API endpoints to update an existing product. Så tar vi inte den delen utan vi tar oss nog den där delen. För den vettare kommer vi att ha intresse av. Det enda vi behöver göra är att uppdatera metoden till en put.
Men vi måste fortfarande specificera. vilken produkt är det vi vill uppdatera. Och sen sätter vi upp en funktion som är här med olika delarna. Där har vi taktant nog möjligheten att kopiera över från den delen där.
Och sen inte data.request.json utan sätta upp data som en variabel. Och sen så vill vi sno den här delen. För vi vill köra någonting mot vår databas.
Och sen så vill vi säga execute. Sedan vill vi egentligen göra på samma sätt som vi gjorde här. För det är de delarna som vi vill uppdatera. Så att jag får med allt relevant här.
Alla de kolumnerna som ska bli drabbade eller uppdaterade. Så. Och så vill vi säga update.
Nu ska jag se om jag har noterat korrekt. Straight Parallax. Det där hade jag ju fel tidigare.
Insert into Parallax. Samma gäller här. Update Parallax.
Set Parallax name till det dynamiska värdet. Så fortsätter vi. Supplier ID, Category ID, Quantity per Unit, Rinse & Repeat arbete som man behöver göra, Unit Price och sen har vi efterföljande Unit Instock.
Så, och så behöver vi se genom att forma villkor. Annars blir det ju bättre svårt. Där vi då inte använder product ID.
Where product ID. Och ordningen på de här arbetardynamiska värdena är relevant. Så här har vi product name som kommer först. Efterföljande kolumner som uppdateras.
Och så säger vi where-klausulen, where product ID ska motsvara någonting. Då ska den komma längst bak. Annars så kommer den att försöka hämta någon annan kolumn som inte är relevant.
Och product ID är det som ska komma från... funktionsargumentet här uppe. Det är därför jag inte har satt upp någon sån via requestet eftersom att det kommer du behöva specificera när du går mot den här endpointen.
Vi säger ju att vi vill uppdatera kanske slash products slash 1 och då kommer ju den, vad heter det, kunna bättre titta på det. I bättre url. Och sen så den data du skickar in. Är det som blir ändrat för den produkten. Så.
Och sen behöver vi säga. Att vi vill. Committa. Connection. Commit.
Och sen returnera något vettigt till slutanvändaren. Message product updated successfully. Och samma där.
En statuskod till slutanvändaren. Men inget mer än så behövs egentligen. Bara en indikation på att saker och ting har utförts i databasen. Sen kommer vi till den lite mer läskigare delen som tillåter oss att ta bort en produkt.
API to delete a product. Upload route, product, if she. Jag tar den delen för den kommer vi att använda oss av.
Men istället för put så vill vi säga delete. Och sen gissningsvis kan ni förstå att vi kommer sätta upp en funktion som heter delete product. Som baserar sig på givetvis ett produkt id. Vi öppnar upp en koppling och sen så vill vi exekvera någonting. Delete from product where product id.
Det kan vara konstigt. Where productID ska vara ett dynamiskt värde. Och det dynamiska värdet ska vara numeriskt. Så trailing komma behövde vara med där i det fallet.
Så vi säger att vi vill ta bort någonting från tabellen produkt. Där produktID är placeholder som är productID i vår funktion. Och det ter sig också på den här endpointen. Så jag antar att ni förstår nu principen av att det är bättre viktigt att det är med i URL.
För annars så kommer den inte förstå vilket produktid det ska göra saker och ting mot. Och sen behöver vi också säga åt databasen att praktiskt utföra det här. Och likväl som tidigare. Så någonting till Product deleted. Deleted Successfully.
Då har vi satt upp en bättre funktion. Eller en point snarare i vårt API. Som tillåter oss att ta bort en produkt. Det är en som tillåter oss att uppdatera en produkt och lägga till en produkt. Och de kolumner som inte tar hänsyn till blir ju null givetvis.
Och sen har vi en hämtning per produkt på id och samtliga produkter. Nu slår vi igång den på nytt. Så att vi inte har några syntaxfel.
Det hade vi inte. Som sagt, jag är ganska begränsad av vad jag kan göra här i webbläsaren med tanke på att här kan jag hämta alla produkter. Och så kan jag hämta en specifik produkt.
Men jag kan inte göra någon post eller putt eller så i webbläsaren rakt av. Då behöver jag använda mig av någon form av verktyg. Och i vårt fall så blir Postman alldeles utmärkt.
Det finns jättebra dokumentation och guider. på hur Wettere Postman fungerar. Om så önskas så kan jag inkludera någon i Discord-server. Som sagt, om vi tar upp koden igen så har vi då möjligheten att kunna köra den här post-metoden.
Det är den jag tänker att vi ska bättre utföra. Var är postman? Där har jag den. Så, och så in med URL-en och end-pointen som vi vill gå emot. Och sen så för att vara snälla mot API-et så säger vi content-type-application-eason.
I vissa fall behövs inte det men jag vill säkerställa att vi verkligen lägger till rätt. Ja. Nu behöver vi bygga på vår json och den ska då inkludera lite olika saker.
Så jag tänker att jag snor den här delen. Och så gör jag om det till json. Och json är egentligen objekt som har key value pairs. Men vi måste följa syntaxen. Det jag hade där var inte syntax som var vänlig för json.
Därav att jag står och gör om allting här. Men nu har jag möjligheten att mata in saker och ting. Så product name. Jag vill ta något exempel som select stjärna från product, limit 5. Har vi något bra?
Vi selectar stjärna från category where category id är lika med 1. Utanför beverages. Okej, så jag ska komma på en dryck. Coca-Cola. Supplier id.
Vad för supplier id blir bra? Kan inte jag sno data från typ Pi? Jo, det kan jag.
Supplier ID är category ID. Här är quantity per unit. Det verkar vara någon textbeskrivning. Vi kör den beskrivningen som var för en annan produkt.
Det viktigaste är att vi lägger in data i rätt format i alla fall. Och sen har vi unit per price. Describe product, unit price and decimal. Då behöver vi ta hänsyn till det, datat. Sen behöver vi ta bort det där.
Vi säger 20, rakt av. Och så unit in stock, verkar vara ett numeriskt värde. Som får bli 10. Okej, vad har vi gjort nu? Vi har byggt upp ett JSON-objekt. Vi lägger till Coca-Cola som ska vara en beverage.
Den ska vara en viss supplier. Och viss typ av konto till oss och så vidare. Och det kräver ju givetvis att vår applikation körs. Så Visual Studio Code, den är aktiv som sagt.
Och så nu har vi testat att köra mot... Över till databasen så ska vi först säkerställa att vi inte har någon sån produkt så att jag inte använder mig av den. En produkt som redan finns. Where product name like kocka.
Nej, ingenting där. Så nu om jag kör det här. Så ser vi att vi får ett meddelande tillbaka. Och statusen 201. Den står för created.
Vad var det jag sa? No content. Och ttp status.
Är det 204 kanske? Ja det är det, 204. 201 står för Created och det är jätte relevant för en post. Nu i Visual Studio Code så ser vi att den har kört Post Products och sagt 201. Så det som återstår att göra är att kolla om den har lagts till i databasen.
Och det har den! Woho! Så det betyder att vi har ett rest API som vi har kopplat mot vår Northwind-databas.
Vi går i och för sig bara mot Product Products. tabellen men vi har en koppling. Har ni frågor eller funderingar så hör av er till mig på Discord och hoppas att ni har nytta av det här demot.
Tack så mycket!