# discord_tools/utils/api_utils.py import os import sys import requests import time # Add the parent directory to the Python path script_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(script_dir)) sys.path.insert(0, project_root) from discord_tools.config.settings import DISCORD_API_BASE_URL, DISCORD_TOKEN, RATE_LIMIT_ATTEMPTS, RATE_LIMIT_DELAY, ERROR_MESSAGES def make_discord_request(method, endpoint, **kwargs): """ Make a request to the Discord API with built-in rate limiting and error handling. :param method: HTTP method (e.g., 'GET', 'POST', 'DELETE') :param endpoint: API endpoint (e.g., '/users/@me') :param kwargs: Additional arguments to pass to the requests function :return: Response object or None if the request failed """ url = f"{DISCORD_API_BASE_URL}{endpoint}" headers = { "Authorization": DISCORD_TOKEN, "Content-Type": "application/json" } headers.update(kwargs.get('headers', {})) kwargs['headers'] = headers for attempt in range(RATE_LIMIT_ATTEMPTS): try: response = requests.request(method, url, **kwargs) response.raise_for_status() return response except requests.exceptions.HTTPError as e: if e.response.status_code == 429: # Rate limited retry_after = e.response.json().get('retry_after', RATE_LIMIT_DELAY) print(f"Rate limited. Retrying in {retry_after} seconds...") time.sleep(retry_after) else: print(f"HTTP Error: {e}") return None except requests.exceptions.RequestException as e: print(f"Request failed: {e}") return None print(ERROR_MESSAGES["rate_limit_exceeded"]) return None def get_user_id(): """ Get the user ID of the authenticated user. :return: User ID as a string, or None if the request failed """ response = make_discord_request('GET', '/users/@me') if response: return response.json()['id'] return None