Robust Request Design
Designing Resilient Network Requests
Request Configuration Parameters
Parameter |
Purpose |
Recommended Setting |
Timeout |
Prevent hanging requests |
5-10 seconds |
Retries |
Handle transient failures |
3 max attempts |
Connection Pooling |
Optimize resource usage |
Reuse connections |
SSL Verification |
Ensure secure connections |
Always enabled |
Comprehensive Request Wrapper
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
class RobustRequestClient:
def __init__(self, base_url, timeout=5, retries=3):
self.base_url = base_url
self.session = requests.Session()
## Retry strategy configuration
retry_strategy = Retry(
total=retries,
backoff_factor=0.3,
status_forcelist=[500, 502, 503, 504]
)
## HTTP adapter with retry mechanism
adapter = HTTPAdapter(max_retries=retry_strategy)
self.session.mount('http://', adapter)
self.session.mount('https://', adapter)
## Default request configuration
self.default_headers = {
'User-Agent': 'LabEx Network Client',
'Accept': 'application/json'
}
self.timeout = timeout
def get(self, endpoint, params=None):
url = f"{self.base_url}/{endpoint}"
try:
response = self.session.get(
url,
params=params,
headers=self.default_headers,
timeout=self.timeout
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
self._handle_request_error(e, url)
def post(self, endpoint, data=None):
url = f"{self.base_url}/{endpoint}"
try:
response = self.session.post(
url,
json=data,
headers=self.default_headers,
timeout=self.timeout
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
self._handle_request_error(e, url)
def _handle_request_error(self, error, url):
error_map = {
requests.exceptions.ConnectionError: "Network Connection Failed",
requests.exceptions.Timeout: "Request Timed Out",
requests.exceptions.HTTPError: "HTTP Error Occurred"
}
error_type = type(error)
error_message = error_map.get(error_type, "Unexpected Request Error")
print(f"Request to {url} failed: {error_message}")
raise
Request Flow Visualization
graph TD
A[Initialize Request Client] --> B[Configure Retry Strategy]
B --> C[Set Default Headers]
C --> D[Prepare Request]
D --> E{Request Successful?}
E -->|Yes| F[Return Response]
E -->|No| G[Retry/Handle Error]
Advanced Request Design Principles
1. Circuit Breaker Pattern
class CircuitBreaker:
def __init__(self, failure_threshold=3, reset_timeout=30):
self.failures = 0
self.state = "CLOSED"
self.threshold = failure_threshold
self.reset_timeout = reset_timeout
self.last_failure_time = None
def record_failure(self):
self.failures += 1
if self.failures >= self.threshold:
self.state = "OPEN"
self.last_failure_time = time.time()
def allow_request(self):
if self.state == "CLOSED":
return True
if self.state == "OPEN":
current_time = time.time()
if current_time - self.last_failure_time >= self.reset_timeout:
self.state = "HALF_OPEN"
return True
return False
return True
Key Recommendations
- Implement comprehensive error handling
- Use connection pooling
- Configure appropriate timeouts
- Implement retry mechanisms
- Use circuit breakers for critical services
LabEx Recommendation
Explore network request design patterns in LabEx's interactive Python environments to build resilient applications.