PYTHON
Secure Server-to-Server API Calls with API Keys
Demonstrate how to securely make server-side API requests using an API key retrieved from environment variables, ensuring sensitive credentials are not hardcoded.
import requests
import os
def call_external_api_securely(endpoint, api_key_env_var='EXTERNAL_API_KEY', base_url='https://api.example.com'):
"""
Makes a secure authenticated call to an external API using an API key.
Args:
endpoint (str): The specific API path (e.g., '/users', '/data').
api_key_env_var (str): The environment variable name holding the API key.
base_url (str): The base URL of the external API.
Returns:
dict: The JSON response from the API.
Raises:
ValueError: If the API key is not found in environment variables.
requests.exceptions.RequestException: For any HTTP or network errors.
"""
api_key = os.getenv(api_key_env_var)
if not api_key:
raise ValueError(f"API key environment variable '{api_key_env_var}' not set. Please set it securely.")
headers = {
'Authorization': f'Bearer {api_key}', # Common pattern: Bearer token
'Content-Type': 'application/json',
'Accept': 'application/json'
}
url = f"{base_url.rstrip('/')}/{endpoint.lstrip('/')}"
print(f"Making GET request to: {url}")
try:
response = requests.get(url, headers=headers, timeout=15)
response.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
return response.json()
except requests.exceptions.HTTPError as e:
print(f"HTTP Error: {e.response.status_code} - {e.response.text}")
raise
except requests.exceptions.ConnectionError as e:
print(f"Connection Error: Could not connect to {url} - {e}")
raise
except requests.exceptions.Timeout as e:
print(f"Timeout Error: Request to {url} timed out - {e}")
raise
except requests.exceptions.RequestException as e:
print(f"An unexpected request error occurred: {e}")
raise
# --- Example Usage ---
if __name__ == "__main__":
# IMPORTANT: In a real application, set this environment variable
# securely, e.g., in your shell, CI/CD pipeline, or secret manager.
# DO NOT hardcode API keys in your code.
os.environ['EXTERNAL_API_KEY'] = 'your_production_api_key_here' # For demonstration
try:
# Replace with a real API endpoint if testing live
# Using JSONPlaceholder as a dummy for public testing
data = call_external_api_securely(
endpoint='/posts/1',
api_key_env_var='EXTERNAL_API_KEY',
base_url='https://jsonplaceholder.typicode.com' # This API does not require auth, but demonstrates the pattern
)
print("
API Response Data:", data)
# Example of an error case (uncomment to test error handling)
# data = call_external_api_securely(endpoint='/non-existent-path', base_url='https://jsonplaceholder.typicode.com')
except ValueError as e:
print(f"Configuration Error: {e}")
except requests.exceptions.RequestException as e:
print(f"API Call Error: {e}")
finally:
# Clean up environment variable for testing script
if 'EXTERNAL_API_KEY' in os.environ:
del os.environ['EXTERNAL_API_KEY']
How it works: This Python function demonstrates how to make a secure server-to-server API call. It retrieves the API key from an environment variable (e.g., `EXTERNAL_API_KEY`) to avoid hardcoding sensitive credentials. The key is then included in the `Authorization` header as a Bearer token, a common practice for authenticating RESTful APIs. The function uses the `requests` library to perform the HTTP `GET` request, includes a timeout, and implements robust error handling for network issues and HTTP status codes.