FastAPI är ett kraftfullt ramverk för att bygga REST API:er, som gör det enkelt att hantera både förfrågningar och data genom olika funktioner och verktyg. En central del av arbetet med API:er är att förstå hur data skickas och tas emot genom vägar (path parameters), frågeparametrar (query parameters) och, framför allt, request body. I denna kapitel beskrivs hur FastAPI bearbetar request body och hur Pydantic-modeller spelar en avgörande roll i att säkerställa att data valideras och hanteras korrekt.

När en klient gör en begäran till en API-server skickas data ofta i request body, och här kommer FastAPI:s förmåga att bearbeta och validera denna data till sin rätt. Ett typiskt användningsområde är när klienten skickar information för att skapa eller uppdatera resurser, som till exempel när nya objekt ska sparas i en databas. FastAPI gör detta genom att använda request body, som kan innehålla JSON-data, och hantera den genom specifika funktioner och moduler som Path, Query och Body.

För att illustrera detta, låt oss titta på ett exempel. När du skapar en ny resurs, exempelvis en bil, kan du använda en POST-begäran för att skicka data i request body. I detta fall skickar du ett JSON-objekt som innehåller information om bilen: märke, modell och produktionsår. FastAPI gör det möjligt att enkelt ta emot och bearbeta denna data med hjälp av en funktion som Body. Till skillnad från parametrar i URL:en (path eller query) är det här nödvändigt att använda Body, eftersom data skickas i själva begärans kropp.

Exempel på hur detta kan se ut i kod är följande:

python
from typing import Dict
from fastapi import FastAPI, Body app = FastAPI() @app.post("/cars") async def new_car(data: Dict = Body(...)): print(data) return {"message": data}

I detta exempel använder vi Body(...) för att indikera att datan är obligatorisk. FastAPI ser till att denna data tas emot och skickas vidare till funktionen, där den kan bearbetas ytterligare, till exempel genom att spara den i en databas. När du kör detta och skickar en POST-begäran till http://localhost:8000/cars med relevant JSON-data kommer FastAPI automatiskt att hantera den och skicka tillbaka ett svar med den mottagna datan.

Men detta är bara början. För att säkerställa att den mottagna datan är korrekt och uppfyller specifika krav, som att bilens årtal måste vara ett heltal, kan vi använda Pydantic. Pydantic är en Python-bibliotek som gör det möjligt att skapa datamodeller som validerar inkommande data. Genom att skapa en Pydantic-modell för de förväntade fälten (t.ex. bilens märke, modell och årtal), kan FastAPI säkerställa att data följer rätt struktur och typ innan den skickas vidare till vår funktion.

Här är ett exempel på hur detta kan implementeras med Pydantic:

python
from fastapi import FastAPI
from pydantic import BaseModel class InsertCar(BaseModel): brand: str model: str year: int app = FastAPI() @app.post("/cars") async def new_car(data: InsertCar): print(data) return {"message": data}

Med denna modell kommer FastAPI att automatiskt validera inkommande data. Om klienten försöker skicka ett JSON-objekt som inte följer den definierade modellen (t.ex. om året är ett strängvärde istället för ett heltal), kommer FastAPI att returnera ett felmeddelande med en detaljerad beskrivning av vad som är fel.

En av de stora fördelarna med att använda Pydantic i FastAPI är att den inte bara validerar data utan även genererar själv-dokumentation av API:et. Detta gör att utvecklare kan arbeta snabbare och med större förtroende, eftersom FastAPI automatiskt hanterar många av de vanliga valideringsuppgifterna och gör det enkelt att hålla API:et säkert och korrekt.

Vidare kan FastAPI hantera mer komplexa scenarier, där du kanske behöver ta emot flera olika typer av data i samma request body. Ett exempel på detta kan vara när du skickar både bilinformation och användardata tillsammans. Detta kan göras genom att definiera flera Pydantic-modeller och använda dem tillsammans i samma funktion.

python
class UserModel(BaseModel): username: str name: str @app.post("/car/user") async def new_car_model(car: InsertCar, user: UserModel, code: int = Body(None)):
return {"car": car, "user": user, "code": code}

I detta exempel tar vi emot både bilinformation och användardata (som ett användarnamn och ett namn), samt en valfri kampanjkod. Genom att använda Pydantic-modeller för både bilen och användaren, kan vi säkerställa att all inkommande data följer rätt struktur och att felaktiga eller ofullständiga begärningar snabbt identifieras.

Det är också viktigt att förstå att även om FastAPI erbjuder kraftfulla funktioner för datahantering, kan det finnas situationer där du behöver arbeta med rå data direkt, utan att använda de inbyggda modellerna. FastAPI ger även möjlighet att använda den råa begäran via Starlette-ramverket, vilket ger mer flexibilitet i vissa fall där du behöver tillgång till hela request-objektet. Men det bör noteras att denna flexibilitet innebär att du missar de inbyggda fördelarna med Pydantic, som är en av de mest kraftfulla funktionerna i FastAPI.

Att förstå hur dessa verktyg och funktioner samverkar är avgörande för att bygga effektiva och robusta REST API:er. Genom att använda Pydantic-modeller för att validera och bearbeta data kan du säkerställa att ditt API är både säkert och lätt att arbeta med, samtidigt som det ger en smidig upplevelse för användare och utvecklare.

Hur skapar man effektiva API:er med FastAPI och Beanie?

FastAPI och Beanie erbjuder en kraftfull och enkel lösning för att bygga webbaserade API:er. Genom att använda dessa verktyg kan utvecklare skapa robusta och högpresterande system för att hantera databaser och servrar, utan att behöva lägga för mycket tid på komplicerade konfigurationer. I denna text beskrivs hur man implementerar en rad grundläggande funktioner i ett API, inklusive hur man hanterar bilinformation, användare och externa tjänster.

I en FastAPI-applikation kan man skapa olika typer av HTTP-metoder som används för att interagera med databasen. Dessa inkluderar GET-, POST-, PUT- och DELETE-metoder för att hämta, skapa, uppdatera och ta bort resurser, exempelvis bilar, från databasen. För att skapa dessa metoder kan man använda Beanie, som är en asynkron ODM (Object-Document Mapper) för MongoDB, vilket gör det möjligt att snabbt och effektivt läsa från och skriva till databasen.

En grundläggande GET-metod som används för att hämta information om en bil baserat på dess ID ser ut som följer:

python
@router.get("/{car_id}", response_model=Car)
async def get_car(car_id: PydanticObjectId):
car =
await Car.get(car_id) if not car: raise HTTPException(status_code=404, detail="Car not found") return car

Denna metod söker efter en bil med hjälp av ID:t och returnerar ett resultat om bilen finns, eller ett felmeddelande om bilen inte hittas.

För att skapa nya bilinstanser används en POST-metod där man hanterar både formulärdata och externa tjänster. När en ny bil skapas kan en bild laddas upp till en tjänst som Cloudinary för att få en URL, som sedan sparas i databasen tillsammans med övrig information om bilen:

python
@router.post(
"/", response_description="Add new car with picture", response_model=Car, status_code=status.HTTP_201_CREATED, ) async def add_car_with_picture( brand: str = Form("brand"), make: str = Form("make"), year: int = Form("year"), cm3: int = Form("cm3"), km: int = Form("km"), price: int = Form("price"), picture: UploadFile = File("picture"), user_data=Depends(auth_handler.auth_wrapper), ): cloudinary_image = cloudinary.uploader.upload( picture.file, folder="FARM2", crop="fill", width=800, gravity="auto" ) picture_url = cloudinary_image["url"] user = await User.get(user_data["user_id"]) car = Car( brand=brand, make=make, year=year, cm3=cm3, km=km, price=price, picture_url=picture_url, user=user, ) return await car.insert(link_rule=WriteRules.WRITE)

I denna metod används Cloudinary för att hantera bilder som uppladdas via formuläret. Efter att bilden har laddats upp, sparas den i databasen tillsammans med bilens övriga information.

För att uppdatera eller ta bort bilar används PUT- och DELETE-metoder. Dessa metoder är designade för att säkerställa att endast de fält som ändras uppdateras i databasen. Detta gör att systemet blir mer effektivt och minskar risken för att oönskade data ska ändras:

python
@router.put("/{car_id}", response_model=Car) async def update_car( car_id: PydanticObjectId, cardata: UpdateCar ): car = await Car.get(car_id) if not car: raise HTTPException(status_code=404, detail="Car not found") updated_car = {
k: v for k, v in cardata.model_dump().items() if v is not None
}
return await car.set(updated_car)

En DELETE-metod kan enkelt radera en bil från databasen genom att anropa delete() på det specifika dokumentet:

python
@router.delete("/{car_id}")
async def delete_car(car_id: PydanticObjectId):
car =
await Car.get(car_id) if not car: raise HTTPException(status_code=404, detail="Car not found") await car.delete()

När dessa metoder är implementerade och testade, kan man börja integrera dem i applikationen genom att importera de relevanta rutterna i app.py. Detta gör det möjligt att centralt hantera alla API-anrop och organisera applikationens struktur på ett rent och effektivt sätt.

Utöver de grundläggande CRUD-operationerna, erbjuder FastAPI även stöd för bakgrundsprocesser via BackgroundTasks. Dessa används för att hantera långvariga operationer, som att skicka e-post eller vänta på externa API-svar, utan att blockera huvudflödet av applikationen. Det gör det möjligt att skicka svar till användaren omedelbart, medan bakgrundsprocessen fortsätter att köras:

python
from fastapi import BackgroundTasks def delayed_task(username: str): sleep(5) print(f"User just logged in: {username}")

En sådan bakgrundsprocess kan användas vid inloggning av användare för att logga eller utföra andra tidskrävande operationer, utan att påverka användarupplevelsen.

FastAPI:s flexibilitet och prestanda gör det till ett utmärkt val för att bygga API:er som hanterar allt från enkla databasoperationer till komplexa bakgrundsprocesser och integrationer med tredjepartstjänster. Men det är viktigt att komma ihåg att medan FastAPI fungerar utmärkt för många typer av applikationer, är det inte alltid det bästa valet för system som kräver omfattande parallellbearbetning eller arbetsfördelning över flera maskiner. För sådana uppgifter är det bättre att använda mer avancerade lösningar som Celery.

Hur man installerar och konfigurerar MongoDB: Lokalt eller i molnet

För att effektivt arbeta med MongoDB är det viktigt att förstå hur man sätter upp databasen på både lokal nivå och i molnet. En lokal installation kan vara praktisk för snabb prototyputveckling utan behov av internetanslutning. Dock, när man går vidare med mer komplexa projekt och behöver en stabil backendlösning, rekommenderas det att använda en moln-baserad lösning som MongoDB Atlas.

MongoDB Atlas erbjuder flera fördelar jämfört med en lokal installation. Det är enkelt att sätta upp och, som du kommer att se, kan du få det att fungera på bara några minuter med en generös gratisversion som är redo för användning. MongoDB hanterar alla operativa aspekter av databasen, inklusive provisioning, skalning, säkerhetskopiering och övervakning. Genom att använda Atlas slipper du mycket av den manuella installationen och kan vara produktiv direkt. Ytterligare fördelar inkluderar hög säkerhet med inbyggd accesskontroll, brandväggar, och detaljerad behörighetsstyrning, samt automatiska säkerhetskopior (beroende på vilket nivå du väljer).

MongoDB är inte bara en databasleverantör utan en fullfjädrad utvecklarplattform med ett brett utbud av teknologier som är utformade för att underlätta arbetet med data och förbättra produktiviteten för utvecklare. Här följer en översikt av de huvudsakliga komponenterna som kommer att användas i de kommande sektionerna:

  1. MongoDB Community Edition: Detta är den gratis versionen av MongoDB som kan köras på alla större operativsystem. Den är användbar för att experimentera med data lokalt.

  2. MongoDB Compass: En grafisk användargränssnitt (GUI) för att hantera, fråga och analysera MongoDB-data i en visuell miljö. Compass är ett moget och användbart verktyg som du kommer att använda i början för att utforska frågor och aggregationer.

  3. MongoDB Atlas: En molntjänst från MongoDB som gör att du slipper administrera databasen manuellt. Denna lösning är en stor anledning till att MongoDB är en central del av FARM-stack.

  4. MongoDB Shell (mongosh): En kommandoradsgränssnitt som gör det möjligt att utföra vanliga CRUD-operationer (create, read, update, delete) på databasen samt administrera databasen genom att skapa och ta bort databaser och starta eller stoppa tjänster.

  5. MongoDB Database Tools: Ett antal kommandoradsverktyg som gör det möjligt för administratörer och utvecklare att importera eller exportera data till och från en databas, samt ge diagnosinformation eller möjliggöra manipulation av stora filer lagrade i MongoDB:s GridFS-system.

För att installera MongoDB och Compass på en Windows-dator kan du följa dessa steg:

  1. Gå till MongoDB Download Center och välj Windows-versionen innan du laddar ner installationsprogrammet.

  2. Kör installationsprogrammet och följ guiden som visas. Om en säkerhetsvarning visas, välj "Ja" för att fortsätta.

  3. Läs licensavtalet, välj att godkänna det och fortsätt.

  4. När du blir ombedd att välja installationsalternativ, välj "Complete" för en fullständig installation.

  5. Följ anvisningarna för att installera MongoDB som en Windows-nätverkstjänst.

  6. Under installationsprocessen kommer du att uppmanas att installera MongoDB Compass, vilket du bör göra genom att markera kryssrutan.

När installationen är klar kan du testa om MongoDB är korrekt installerat genom att öppna kommandoraden och skriva mongosh. Om installationen är korrekt bör du se en liten prompt där du kan skriva kommandon som show dbs för att visa de automatiskt skapade databaserna som admin, config och local.

Efter installationen kan du även kontrollera installationen av MongoDB Compass. På Windows bör du hitta det i Start-menyn under "MongoDBCompass". Genom att klicka på "Connect" utan att skriva in någon anslutningssträng kommer Compass att ansluta till den lokala MongoDB-tjänsten och du ska kunna se samma databaser som visades via kommandoraden.

Det finns också andra användbara verktyg i MongoDB Database Tools som mongoimport, mongoexport, och mongodump. Dessa verktyg kan användas för att importera och exportera data, samt skapa säkerhetskopior av databaser. De är avgörande när du arbetar med större dataset eller när du behöver hantera data mellan olika MongoDB-instanssystem.

För att installera MongoDB Shell (mongosh) följer du en liknande process genom att ladda ner det från MongoDB:s nedladdningscenter och köra installationsprogrammet. När installationen är klar kan du testa det genom att skriva kommandot mongosh i en kommandorad.

Det är viktigt att förstå att dessa verktyg och tjänster inte bara är användbara för att skapa och administrera databaser utan också för att förbättra säkerheten och säkerställa databasens tillgänglighet. Genom att använda verktygen i MongoDB:s ekosystem kan utvecklare snabbt skapa och hantera robusta datalösningar som är både skalbara och säkra.