Add exponential backoff for Google API calls
- Use backoff library with 5s base, max 5 tries for HttpError 429/5xx - Decorate Google functions: ensure_calendar, fetch_events, create/update/delete events - Add backoff to requirements.txt
This commit is contained in:
@@ -6,3 +6,4 @@ redis
|
|||||||
python-dotenv
|
python-dotenv
|
||||||
google-api-python-client
|
google-api-python-client
|
||||||
google-auth
|
google-auth
|
||||||
|
backoff
|
||||||
@@ -4,6 +4,7 @@ import os
|
|||||||
import datetime
|
import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import pytz
|
import pytz
|
||||||
|
import backoff
|
||||||
from googleapiclient.discovery import build
|
from googleapiclient.discovery import build
|
||||||
from googleapiclient.errors import HttpError
|
from googleapiclient.errors import HttpError
|
||||||
from google.oauth2 import service_account
|
from google.oauth2 import service_account
|
||||||
@@ -60,6 +61,7 @@ async def get_google_service():
|
|||||||
logger.error(f"Failed to initialize Google service: {e}")
|
logger.error(f"Failed to initialize Google service: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@backoff.on_exception(backoff.expo, HttpError, max_tries=5, base=5, giveup=lambda e: e.resp.status not in [429, 500, 502, 503, 504])
|
||||||
async def ensure_google_calendar(service, employee_kuerzel):
|
async def ensure_google_calendar(service, employee_kuerzel):
|
||||||
"""Ensure Google Calendar exists for employee."""
|
"""Ensure Google Calendar exists for employee."""
|
||||||
calendar_name = f"AW-{employee_kuerzel}"
|
calendar_name = f"AW-{employee_kuerzel}"
|
||||||
@@ -106,6 +108,7 @@ async def fetch_advoware_appointments(advoware, employee_kuerzel):
|
|||||||
logger.error(f"Failed to fetch Advoware appointments: {e}")
|
logger.error(f"Failed to fetch Advoware appointments: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@backoff.on_exception(backoff.expo, HttpError, max_tries=5, base=5, giveup=lambda e: e.resp.status not in [429, 500, 502, 503, 504])
|
||||||
async def fetch_google_events(service, calendar_id):
|
async def fetch_google_events(service, calendar_id):
|
||||||
"""Fetch Google events in range."""
|
"""Fetch Google events in range."""
|
||||||
try:
|
try:
|
||||||
@@ -287,6 +290,7 @@ async def delete_advoware_appointment(advoware, frnr):
|
|||||||
logger.error(f"Failed to delete Advoware appointment {frnr}: {e}")
|
logger.error(f"Failed to delete Advoware appointment {frnr}: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@backoff.on_exception(backoff.expo, HttpError, max_tries=5, base=5, giveup=lambda e: e.resp.status not in [429, 500, 502, 503, 504])
|
||||||
async def create_google_event(service, calendar_id, data):
|
async def create_google_event(service, calendar_id, data):
|
||||||
"""Create Google event from standardized data."""
|
"""Create Google event from standardized data."""
|
||||||
start_dt = data['start'].astimezone(BERLIN_TZ)
|
start_dt = data['start'].astimezone(BERLIN_TZ)
|
||||||
@@ -320,6 +324,7 @@ async def create_google_event(service, calendar_id, data):
|
|||||||
logger.error(f"Failed to create Google event: {e}")
|
logger.error(f"Failed to create Google event: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@backoff.on_exception(backoff.expo, HttpError, max_tries=5, base=5, giveup=lambda e: e.resp.status not in [429, 500, 502, 503, 504])
|
||||||
async def update_google_event(service, calendar_id, event_id, data):
|
async def update_google_event(service, calendar_id, event_id, data):
|
||||||
"""Update Google event."""
|
"""Update Google event."""
|
||||||
start_dt = data['start'].astimezone(BERLIN_TZ)
|
start_dt = data['start'].astimezone(BERLIN_TZ)
|
||||||
@@ -351,6 +356,7 @@ async def update_google_event(service, calendar_id, event_id, data):
|
|||||||
logger.error(f"Failed to update Google event {event_id}: {e}")
|
logger.error(f"Failed to update Google event {event_id}: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@backoff.on_exception(backoff.expo, HttpError, max_tries=5, base=5, giveup=lambda e: e.resp.status not in [429, 500, 502, 503, 504])
|
||||||
async def delete_google_event(service, calendar_id, event_id):
|
async def delete_google_event(service, calendar_id, event_id):
|
||||||
"""Delete Google event."""
|
"""Delete Google event."""
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user