Lichtgewicht offloading met BackgroundTasks
Gebruik de ingebouwde BackgroundTasks van FastAPI voor fire-and-forget-neveneffecten zonder de response te blokkeren.
Lichtgewicht offloading met BackgroundTasks is een gratis Bootcamp backendontwikkeling met FastAPI-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Bootcamp backendontwikkeling met FastAPI. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Bootcamp backendontwikkeling met FastAPI bevat in totaal 4 lessen.
Waarom werk uitbesteden?
Wanneer een client een verzoek stuurt, wacht die op het antwoord. Als je eindpunt ook een welkomstmail verstuurt, een auditlogboek schrijft of een cache opwarmt, moet de gebruiker wachten op werk waar die niet om geeft.
Bijwerkingen zonder wachten zijn taken die na het versturen van het antwoord moeten worden uitgevoerd zonder het antwoord te blokkeren:
- Meldingsmails versturen
- Analyse- of auditlogboeken schrijven
- Caches ongeldig maken of opwarmen
- Tijdelijke bestanden opruimen
FastAPI bevat hiervoor precies het juiste ingebouwde hulpmiddel: BackgroundTasks.
BackgroundTasks declareren
Voeg hiervoor aan je padbewerkingsfunctie een parameter toe met het type BackgroundTasks. FastAPI ziet de typeannotatie en injecteert automatisch een exemplaar voor je, net als bij elke andere afhankelijkheid.
Vervolgens registreer je werk met .add_task(func, *args, **kwargs). De functie wordt niet onmiddellijk aangeroepen, maar in de wachtrij geplaatst om te worden uitgevoerd zodra het antwoord is teruggestuurd.
from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
def write_log(message: str) -> None:
with open("log.txt", mode="a") as f:
f.write(message + "\n")
@app.post("/signup")
async def signup(email: str, tasks: BackgroundTasks):
tasks.add_task(write_log, f"signup: {email}")
return {"status": "accepted"}De uitvoeringsvolgorde
Het belangrijkste detail: achtergrondtaken worden nadat het antwoord naar de client is verstuurd uitgevoerd, maar nog steeds binnen hetzelfde serverproces.
- Het eindpunt retourneert zijn
dictofResponse. - FastAPI stuurt het antwoord via het netwerk.
- Pas daarna voert het elke taak in de wachtrij uit, in de volgorde waarin ze zijn toegevoegd.
De gebruiker krijgt dus een direct antwoord in de stijl van 202, terwijl de e-mail of het logboek op de achtergrond wordt verwerkt.
Argumenten aan een taak doorgeven
Argumenten die je aan add_task doorgeeft, worden opgeslagen en doorgegeven wanneer de taak uiteindelijk wordt uitgevoerd. Zowel positionele als benoemde argumenten werken.
Met dit patroon blijft de logica voor bijwerkingen in een gewone functie staan, die je eenvoudig afzonderlijk als eenheidstest kunt testen, volledig onafhankelijk van FastAPI.
from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
def send_email(to: str, subject: str, body: str) -> None:
# imagine an SMTP client here
print(f"Sending to {to}: {subject}")
@app.post("/orders")
async def create_order(email: str, tasks: BackgroundTasks):
order_id = 1234
tasks.add_task(
send_email,
to=email,
subject="Order confirmed",
body=f"Your order {order_id} is on the way!",
)
return {"order_id": order_id}Synchrone versus asynchrone taakfuncties
Een taakfunctie kan een normale def of een async def zijn.
- Een asynchrone taak wordt rechtstreeks in de gebeurtenislus afgewacht.
- Een gewone
def-taak wordt in een threadpool uitgevoerd, zodat die de lus niet blokkeert.
Vuistregel: als je bijwerking blokkerende I/O uitvoert (bestanden schrijven of een synchrone database-driver gebruiken), volstaat een gewone def; FastAPI besteedt die uit aan een thread. Gebruik async def alleen wanneer je daadwerkelijk asynchrone I/O afwacht.
async def notify_async(user_id: int) -> None:
# awaits an async HTTP client, for example
await some_async_push(user_id)
def notify_sync(user_id: int) -> None:
# blocking call, run in a threadpool by FastAPI
requests_post(user_id)Meerdere taken toevoegen
Je kunt zo vaak als je wilt add_task aanroepen. Taken worden achtereenvolgens uitgevoerd, precies in de volgorde waarin ze zijn toegevoegd; elke taak wordt afgerond voordat de volgende begint.
Omdat ze na elkaar worden uitgevoerd, vertraagt een trage taak de taken die erachter in de wachtrij staan, maar nooit het HTTP-antwoord zelf.
from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
@app.post("/publish")
async def publish(post_id: int, tasks: BackgroundTasks):
tasks.add_task(reindex_search, post_id)
tasks.add_task(invalidate_cache, post_id)
tasks.add_task(notify_followers, post_id)
return {"published": post_id}BackgroundTasks in afhankelijkheden gebruiken
Een krachtige truc: een afhankelijkheid kan ook een parameter BackgroundTasks declareren en taken in de wachtrij plaatsen. FastAPI voegt alles samen in één gedeelde verzameling taken voor dat verzoek.
Zo kunnen zaken die op meerdere plaatsen nodig zijn, zoals auditlogboekregistratie, in een herbruikbare afhankelijkheid staan in plaats van in elk eindpunt te worden gekopieerd.
from fastapi import BackgroundTasks, Depends, FastAPI
app = FastAPI()
def audit(action: str, tasks: BackgroundTasks):
tasks.add_task(write_audit_row, action)
return action
@app.delete("/items/{item_id}")
async def delete_item(item_id: int, action=Depends(audit)):
return {"deleted": item_id}Een mentaal model van een taakwachtrij in gewone Python
Onder de motorkap is BackgroundTasks niet veel meer dan een lijst van aanroepbare objecten die na het antwoord worden uitgevoerd. Je kunt het idee in pure Python modelleren om er gevoel voor te krijgen.
Het onderstaande fragment staat op zichzelf, vereist geen FastAPI en laat het patroon zien waarbij je iets toevoegt om het later uit te voeren.
class TaskList:
def __init__(self):
self.tasks = []
def add_task(self, func, *args, **kwargs):
self.tasks.append((func, args, kwargs))
def run_all(self):
for func, args, kwargs in self.tasks:
func(*args, **kwargs)
def log(msg):
print("LOG:", msg)
q = TaskList()
q.add_task(log, "user signed up")
q.add_task(log, "email queued")
print("response sent")
q.run_all()Foutafhandeling binnen taken
Omdat een taak na het antwoord wordt uitgevoerd, kun je een fout daarin niet meer omzetten in een HTTP-fout; de client heeft al een 200 ontvangen.
Een onverwerkte uitzondering in een achtergrondtaak wordt door de server vastgelegd, maar is onzichtbaar voor de client. Plaats riskant werk altijd in try/except en bepaal zelf of je opnieuw probeert of een strategie voor onbestelbare berichten gebruikt.
def send_receipt(order_id: int) -> None:
try:
deliver_email(order_id)
except Exception as exc:
# the client already has its 200, so log and recover here
logger.exception("receipt failed for %s: %s", order_id, exc)
schedule_retry(order_id)De grote beperking: hetzelfde proces
BackgroundTasks wordt uitgevoerd in hetzelfde workerproces als je app. Dat brengt echte beperkingen met zich mee:
- Zwaar CPU-werk gebruikt nog steeds de resources van dat workerproces.
- Als het proces crasht of opnieuw wordt uitgerold, gaan taken in de wachtrij verloren; er is geen persistentie.
- Taken blijven niet behouden op meerdere machines en kunnen niet horizontaal worden geschaald.
Het is perfect voor lichte, best-effort-neveneffecten, maar niet voor betrouwbare, langdurige of gedistribueerde taken.
Wanneer je beter Celery kunt gebruiken
Kies BackgroundTasks wanneer het werk kort en niet-kritiek is en het geen probleem is als het bij een crash verloren gaat, zoals een e-mail versturen, een teller verhogen of een tijdelijk bestand verwijderen.
Kies Celery of een andere gedistribueerde wachtrij (RQ, Dramatiq, Arq) wanneer je het volgende nodig hebt:
- Duurzaamheid: taken blijven na herstarts behouden via een broker zoals Redis/RabbitMQ.
- Opnieuw proberen, plannen en snelheidsbeperking.
- Horizontaal schalen over speciale workermachines.
- Zware CPU-taken die anders je webworkers zouden uithongeren.
Korte controle
Test je begrip van wanneer BackgroundTasks het juiste hulpmiddel is.
Samenvatting
Belangrijkste punten:
- Voeg een parameter
BackgroundTaskstoe en roepadd_task(func, *args, **kwargs)aan om neveneffecten uit te stellen. - Taken worden na de respons sequentieel uitgevoerd in hetzelfde workerproces.
- Synchrone
def-taken worden uitgevoerd in een threadpool;async def-taken op de eventlus. - Afhankelijkheden kunnen ook taken in de wachtrij plaatsen, wat handig is voor dwarsdoorsnijdende aandachtspunten zoals auditing.
- Geen persistentie: fouten zijn onzichtbaar voor de client en taken stoppen wanneer het proces stopt.
- Gebruik het voor licht, best-effort-werk; kies Celery voor duurzame, opnieuw uitvoerbare, gedistribueerde of CPU-intensieve taken.
Leer Bootcamp backendontwikkeling met FastAPI met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 21
- Lessen
- 84
Veelgestelde vragen
Is de les “Lichtgewicht offloading met BackgroundTasks” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Bootcamp backendontwikkeling met FastAPI, waaronder “Lichtgewicht offloading met BackgroundTasks”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Bootcamp backendontwikkeling met FastAPI bevat in totaal 4 lessen.
Wat leer ik in “Lichtgewicht offloading met BackgroundTasks”?
Gebruik de ingebouwde BackgroundTasks van FastAPI voor fire-and-forget-neveneffecten zonder de response te blokkeren. Je oefent met Bootcamp backendontwikkeling met FastAPI door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Bootcamp backendontwikkeling met FastAPI te beginnen?
Ervaring vooraf is niet nodig. Bootcamp backendontwikkeling met FastAPI op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Lichtgewicht offloading met BackgroundTasks”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Bootcamp backendontwikkeling met FastAPI?
Ja. Elke les over Bootcamp backendontwikkeling met FastAPI bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Lichtgewicht offloading met BackgroundTasks
- Celery-workers koppelen aan een FastAPI-app
- Retries, idempotentie en dead-letterafhandeling
- Geplande en periodieke jobs met Celery Beat