Python is de favoriet voor scripts, data-pipelines en automatisering. De officiele Google-clientbibliotheek voor Python werkt met elke Workspace-API via hetzelfde fluent patroon. Of je nu een eenmalig script schrijft of een serverproces draait, de opzet is altijd hetzelfde.
In dit artikel installeer je de bibliotheken, regel je authenticatie en doe je je eerste calls, inclusief paginering en nette foutafhandeling.
Installatie
Je hebt twee pakketten nodig: de clientbibliotheek en de auth-bibliotheek. Voor OAuth-flows komt daar nog een helper bij.
pip install google-api-python-client google-auth google-auth-oauthlib
Pin je versies en draai een audit
Pin de versies in je requirements.txt of pyproject.toml en draai pip-audit na installatie. Zo weet je dat je geen kwetsbare versies binnenhaalt en blijft je build reproduceerbaar. Recente versies van google-api-python-client (de 2.x-reeks) cachen de discovery-documenten in het pakket zelf, waardoor de installatie groter is maar build() niet meer afhankelijk is van een netwerk-call naar de discovery-service.
Authenticeren met een service account
Voor server-naar-server gebruik je google.oauth2.service_account met de gewenste scopes. Dit is de aangewezen methode voor achtergrondprocessen zonder gebruiker aan de knoppen.
from google.oauth2 import service_account
from googleapiclient.discovery import build
SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly']
creds = service_account.Credentials.from_service_account_file(
'/secrets/sa-key.json', scopes=SCOPES
)
service = build('sheets', 'v4', credentials=creds)
Behandel je sleutel als een wachtwoord
Een service-account-JSON geeft directe toegang. Commit de sleutel nooit in Git, plaats hem buiten je webroot en lees hem bij voorkeur uit een secret manager in plaats van een bestand op schijf. Beperk de scopes tot precies wat het script nodig heeft.
Authenticeren met OAuth
Voor data van een ingelogde gebruiker gebruik je een interactieve flow die een token opslaat voor hergebruik.
from google_auth_oauthlib.flow import InstalledAppFlow
from google.oauth2.credentials import Credentials
flow = InstalledAppFlow.from_client_secrets_file('client_secret.json', SCOPES)
creds = flow.run_local_server(port=0)
Hergebruik de token bij de volgende run
Sla de verkregen credentials op als JSON en herlaad ze met Credentials.from_authorized_user_file. Zo hoeft de gebruiker niet elke keer opnieuw in te loggen, want de refresh token blijft geldig totdat hij wordt ingetrokken of verloopt.
Je eerste call
Het patroon is fluent: je bouwt een verzoek op en sluit af met execute().
Zo doe je je eerste call
- Bouw de service met
build(naam, versie, credentials=creds). - Navigeer naar de resource, bijvoorbeeld
service.spreadsheets().values(). - Roep de methode aan met named parameters.
- Sluit af met
.execute()om het verzoek te versturen. - Lees het resultaat uit als dictionary.
result = service.spreadsheets().values().get(
spreadsheetId=SHEET_ID, range='A1:C10'
).execute()
rijen = result.get('values', [])
Paginering
Lijst-endpoints retourneren een nextPageToken. Veel resources bieden een list_next-helper die dit voor je afhandelt, zodat je niet zelf met tokens hoeft te jongleren.
request = service.files().list(pageSize=100)
while request is not None:
response = request.execute()
verwerk(response.get('files', []))
request = service.files().list_next(request, response)
Foutafhandeling
Vang HttpError op en gebruik backoff
Vang HttpError uit googleapiclient.errors op. De statuscode zit in error.resp.status. Bij 429 of bij 403 met rateLimitExceeded moet je opnieuw proberen met exponential backoff. Bouw dit niet pas in als het al misgaat in productie.
from googleapiclient.errors import HttpError
try:
service.files().list().execute()
except HttpError as e:
print(f'Fout {e.resp.status}: {e}')
Een eenvoudige backoff houdt je script overeind bij tijdelijke limieten:
import time
from googleapiclient.errors import HttpError
def met_backoff(verzoek, pogingen=5):
for poging in range(pogingen):
try:
return verzoek.execute()
except HttpError as e:
if e.resp.status in (429, 403) and poging < pogingen - 1:
time.sleep(2 ** poging)
continue
raise
Veelgestelde vragen
Wat is het verschil tussen google-api-python-client en de cloud-bibliotheken?
De google-api-python-client dekt de discovery-API's zoals de meeste Workspace-diensten. De cloud-bibliotheken (google-cloud-*) zijn specifiek voor Google Cloud-diensten en hebben een eigen, vaak idiomatischer idioom met getypte objecten in plaats van dictionaries.
Hoe stel ik impersonation (domain-wide delegation) in?
Roep creds.with_subject('gebruiker@domein.nl') aan op een service-account-credential waarvoor domain-wide delegation is geactiveerd in de Admin-console. Het script handelt dan namens die gebruiker.
Kan ik async werken?
De officiele client is synchroon. Voor async draai je calls in een threadpool (bijvoorbeeld via asyncio.to_thread) of gebruik je een community-bibliotheek met asyncio-ondersteuning.
Hoe weet ik welke methoden beschikbaar zijn?
Raadpleeg de API-referentie van de betreffende dienst, of gebruik de ingebouwde discovery: de service-objecten spiegelen de API-structuur exact, dus dir() op een resource toont de beschikbare methoden.
Waarom is mijn installatie zo groot geworden?
De 2.x-reeks bundelt de discovery-documenten in het pakket zodat build() geen netwerk-call meer hoeft te doen. Dat maakt de installatie tientallen megabytes groter, maar betrouwbaarder en sneller bij het opstarten.
Met deze opzet schrijf je in Python betrouwbare, herhaalbare integraties met elke Workspace-API.