Google Drive is de centrale opslag van Workspace, en met de Drive API maak je die volledig scriptbaar. Je uploadt rapporten, organiseert mappen, beheert wie wat mag zien en houdt wijzigingen bij. Voor backup-systemen, document-pipelines en integraties is dit een van de meest gebruikte API's.
In dit artikel bouw je de kernoperaties op met de Drive API v3 en de officiele google-api-python-client.
De service opzetten
Eerst bouw je een service-object met je credentials. Voor servertaken gebruik je doorgaans een service-account met de juiste OAuth-scopes.
from googleapiclient.discovery import build
service = build("drive", "v3", credentials=credentials)
De scope https://www.googleapis.com/auth/drive.file geeft toegang tot bestanden die je app zelf aanmaakt of opent. Voor volledige toegang gebruik je https://www.googleapis.com/auth/drive, maar vraag altijd de smalst mogelijke scope aan.
Een bestand uploaden
Uploaden combineert metadata met de bestandsinhoud via een MediaFileUpload.
from googleapiclient.http import MediaFileUpload
metadata = {"name": "rapport.pdf", "parents": [MAP_ID]}
media = MediaFileUpload("rapport.pdf", mimetype="application/pdf")
bestand = service.files().create(
body=metadata, media_body=media, fields="id"
).execute()
print(bestand["id"])
Waar belandt het bestand?
Het parents-veld bepaalt in welke map het bestand komt. Laat je het weg, dan belandt het in de hoofdmap van Drive. Een bestand kan in de nieuwe Drive maar in een enkele map tegelijk staan.
Voor grote bestanden zet je resumable=True, zodat een onderbroken upload hervat in plaats van opnieuw begint.
media = MediaFileUpload("groot-bestand.zip", resumable=True)
request = service.files().create(body=metadata, media_body=media, fields="id")
respons = None
while respons is None:
status, respons = request.next_chunk()
Zoeken met de query-syntax
De q-parameter is krachtig. Je filtert op naam, type, map, eigenaar en meer.
resultaat = service.files().list(
q="mimeType='application/pdf' and '" + MAP_ID + "' in parents and trashed=false",
fields="files(id, name)"
).execute()
for f in resultaat.get("files", []):
print(f["name"], f["id"])
Sneller en gerichter zoeken
Combineer voorwaarden met and en or, en gebruik trashed=false om verwijderde bestanden uit te sluiten. Vraag met de fields-parameter alleen de velden op die je nodig hebt, dat versnelt grote zoekopdrachten merkbaar. Voor lange resultaten blader je verder met de teruggegeven nextPageToken.
Bestanden delen
Toegang regel je via de permissions-resource. Je kent een rol toe aan een gebruiker, groep, domein of iedereen.
Toegang verlenen en intrekken
- Bepaal wie toegang krijgt en met welke rol (
reader,commenter,writer). - Roep
permissions().create()aan mettypeenemailAddress. - Zet
sendNotificationEmailop de gewenste waarde. - Voor intrekken gebruik je
permissions().delete()met het permission-ID.
permissie = {"type": "user", "role": "writer", "emailAddress": "collega@bedrijf.nl"}
service.permissions().create(
fileId=BESTAND_ID, body=permissie, sendNotificationEmail=True
).execute()
Pas op met openbaar delen
Wees voorzichtig met het type anyone, dat maakt een bestand toegankelijk voor iedereen met de link. Voor gevoelige documenten gebruik je altijd type user of group met expliciete adressen, en audit je periodiek welke bestanden breed gedeeld zijn.
Downloaden
Voor binaire bestanden gebruik je get_media en een downloader die in stukken werkt.
from googleapiclient.http import MediaIoBaseDownload
import io
request = service.files().get_media(fileId=BESTAND_ID)
buffer = io.BytesIO()
downloader = MediaIoBaseDownload(buffer, request)
klaar = False
while not klaar:
status, klaar = downloader.next_chunk()
Voor Google-eigen formaten zoals Docs, Sheets en Slides bestaat er geen ruwe bestandsinhoud. Die exporteer je met files().export_media() naar een doelformaat, bijvoorbeeld PDF.
request = service.files().export_media(
fileId=DOC_ID, mimeType="application/pdf"
)
Wijzigingen volgen
Voor synchronisatie volg je de changes-resource. Eerst haal je een startpunt op met changes().getStartPageToken(), daarna verwerk je met changes().list() alleen wat er sinds dat token veranderd is. Dit werkt vergelijkbaar met de syncToken bij Calendar.
token = service.changes().getStartPageToken().execute()["startPageToken"]
wijzigingen = service.changes().list(pageToken=token).execute()
Werk met gedeelde Drives
Wil je ook gedeelde Drives meenemen, geef dan supportsAllDrives=True en includeItemsFromAllDrives=True mee in je calls. Zonder deze vlaggen zie je alleen Mijn Drive.
Veelgestelde vragen
Wat is het verschil tussen Mijn Drive en gedeelde Drives?
Gedeelde Drives horen bij een team in plaats van een persoon. Geef supportsAllDrives=True mee in je calls om ermee te werken, en voor zoekopdrachten ook includeItemsFromAllDrives=True.
Hoe upload ik grote bestanden betrouwbaar?
Gebruik resumable uploads door resumable=True bij MediaFileUpload te zetten en daarna next_chunk() te herhalen. Bij een onderbreking hervat de upload in plaats van opnieuw te beginnen.
Kan ik een Google Doc programmatisch exporteren naar PDF?
Ja, met files().export_media() en mimeType application/pdf. Let op: export_media() is voor Google-eigen formaten, voor gewone bestanden gebruik je get_media().
Hoe vind ik de map-ID?
Open de map in de browser, het laatste deel van de URL is de ID. Of zoek ernaar met files().list() op naam en mimeType='application/vnd.google-apps.folder'.
Welke OAuth-scope heb ik nodig?
Voor bestanden die je app zelf aanmaakt of opent volstaat drive.file. Pas wanneer je echt alle bestanden van een gebruiker moet beheren gebruik je de bredere drive-scope. Vraag altijd de smalst mogelijke scope aan.
Waarom krijg ik een 403-fout bij het delen?
Meestal ontbreekt de juiste scope, of de service-account is geen lid van de gedeelde Drive. Controleer de scopes en voeg de service-account toe als lid met voldoende rechten.
Met de Drive API in Python bouw je betrouwbare document-pipelines, backups en integraties die je opslag volledig automatiseren.