Library for accessing Swagger-enabled APIs
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete HTTP status code exception hierarchy with timeout and connection error handling. Bravado provides specific exceptions for all HTTP status codes plus bravado-specific errors, enabling precise error handling for robust applications.
Unified HTTP error base class that all HTTP-related exceptions inherit from. Contains response data and optional swagger result.
class HTTPError(IOError):
status_code: int
def __init__(self, response, message: str = None, swagger_result=None): ...
def __str__(self) -> str: ...Attributes:
status_code (int): HTTP status code associated with this exception typeresponse: IncomingResponse object containing the HTTP response detailsmessage (str): Optional custom error messageswagger_result: Parsed response data if availableUsage Example:
from bravado.exception import HTTPError, HTTPNotFound
try:
pet = client.pet.getPetById(petId=999).response().result
except HTTPNotFound as e:
print(f"Pet not found: {e}")
print(f"Status code: {e.status_code}")
print(f"Response body: {e.response.text}")
except HTTPError as e:
print(f"HTTP error {e.status_code}: {e}")Bravado organizes HTTP exceptions into logical categories:
Base class for 3xx redirection responses.
class HTTPRedirection(HTTPError): ...Specific 3xx Exceptions:
HTTPMultipleChoices (300)HTTPMovedPermanently (301)HTTPFound (302)HTTPSeeOther (303)HTTPNotModified (304)HTTPUseProxy (305)HTTPTemporaryRedirect (307)HTTPPermanentRedirect (308)Base class for 4xx client error responses.
class HTTPClientError(HTTPError): ...Common 4xx Exceptions:
HTTPBadRequest (400) - Invalid request syntax or parametersHTTPUnauthorized (401) - Authentication required or failedHTTPPaymentRequired (402) - Payment requiredHTTPForbidden (403) - Access deniedHTTPNotFound (404) - Resource not foundHTTPMethodNotAllowed (405) - HTTP method not supportedHTTPNotAcceptable (406) - Cannot produce acceptable responseHTTPRequestTimeout (408) - Request timeoutHTTPConflict (409) - Request conflicts with current stateHTTPGone (410) - Resource permanently removedHTTPUnprocessableEntity (422) - Validation errorsHTTPTooManyRequests (429) - Rate limit exceededAll 4xx Exceptions:
class HTTPBadRequest(HTTPClientError): status_code = 400
class HTTPUnauthorized(HTTPClientError): status_code = 401
class HTTPPaymentRequired(HTTPClientError): status_code = 402
class HTTPForbidden(HTTPClientError): status_code = 403
class HTTPNotFound(HTTPClientError): status_code = 404
class HTTPMethodNotAllowed(HTTPClientError): status_code = 405
class HTTPNotAcceptable(HTTPClientError): status_code = 406
class HTTPProxyAuthenticationRequired(HTTPClientError): status_code = 407
class HTTPRequestTimeout(HTTPClientError): status_code = 408
class HTTPConflict(HTTPClientError): status_code = 409
class HTTPGone(HTTPClientError): status_code = 410
class HTTPLengthRequired(HTTPClientError): status_code = 411
class HTTPPreconditionFailed(HTTPClientError): status_code = 412
class HTTPPayloadTooLarge(HTTPClientError): status_code = 413
class HTTPURITooLong(HTTPClientError): status_code = 414
class HTTPUnsupportedMediaType(HTTPClientError): status_code = 415
class HTTPRangeNotSatisfiable(HTTPClientError): status_code = 416
class HTTPExpectationFailed(HTTPClientError): status_code = 417
class HTTPMisdirectedRequest(HTTPClientError): status_code = 421
class HTTPUnprocessableEntity(HTTPClientError): status_code = 422
class HTTPLocked(HTTPClientError): status_code = 423
class HTTPFailedDependency(HTTPClientError): status_code = 424
class HTTPUpgradeRequired(HTTPClientError): status_code = 426
class HTTPPreconditionRequired(HTTPClientError): status_code = 428
class HTTPTooManyRequests(HTTPClientError): status_code = 429
class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): status_code = 431
class HTTPUnavailableForLegalReasons(HTTPClientError): status_code = 451Base class for 5xx server error responses. Includes response text in string representation for debugging.
class HTTPServerError(HTTPError): ...Common 5xx Exceptions:
HTTPInternalServerError (500) - Server internal errorHTTPNotImplemented (501) - Server does not support functionalityHTTPBadGateway (502) - Invalid response from upstream serverHTTPServiceUnavailable (503) - Server temporarily unavailableHTTPGatewayTimeout (504) - Upstream server timeoutHTTPHTTPVersionNotSupported (505) - HTTP version not supportedAll 5xx Exceptions:
class HTTPInternalServerError(HTTPServerError): status_code = 500
class HTTPNotImplemented(HTTPServerError): status_code = 501
class HTTPBadGateway(HTTPServerError): status_code = 502
class HTTPServiceUnavailable(HTTPServerError): status_code = 503
class HTTPGatewayTimeout(HTTPServerError): status_code = 504
class HTTPHTTPVersionNotSupported(HTTPServerError): status_code = 505
class HTTPVariantAlsoNegotiates(HTTPServerError): status_code = 506
class HTTPInsufficientStorage(HTTPServerError): status_code = 507
class HTTPLoopDetected(HTTPServerError): status_code = 508
class HTTPNotExtended(HTTPServerError): status_code = 510
class HTTPNetworkAuthenticationRequired(HTTPServerError): status_code = 511Bravado-specific exceptions for connection and transport-level issues.
class BravadoTimeoutError(TimeoutError): ...
class BravadoConnectionError(ConnectionError): ...
class ForcedFallbackResultError(Exception): ...BravadoTimeoutError: Raised when requests exceed configured timeout values. BravadoConnectionError: Raised when connection to the server cannot be established. ForcedFallbackResultError: Used internally to force fallback result behavior.
Utility function to create appropriate HTTP exceptions from responses.
def make_http_exception(response, message: str = None, swagger_result=None) -> HTTPError: ...Parameters:
response: IncomingResponse objectmessage (str): Optional custom error messageswagger_result: Parsed response data if availableReturns:
Usage Example:
from bravado.exception import make_http_exception
# Manually create exception from response
try:
# ... some HTTP operation
pass
except Exception as e:
if hasattr(e, 'response'):
http_exception = make_http_exception(e.response, "Custom error message")
raise http_exceptionAll HTTP status codes are mapped to their corresponding exception classes:
status_map: dict # Mapping of int status codes to exception classesThis dictionary maps HTTP status codes to their corresponding exception classes and is used internally by the exception factory.
from bravado.exception import HTTPClientError, HTTPServerError, BravadoTimeoutError
try:
response = client.pet.getPetById(petId=1).response()
pet = response.result
except HTTPClientError as e:
if e.status_code == 404:
print("Pet not found")
elif e.status_code == 401:
print("Authentication required")
else:
print(f"Client error: {e.status_code}")
except HTTPServerError as e:
print(f"Server error: {e.status_code}")
print(f"Response: {e.response.text}")
except BravadoTimeoutError:
print("Request timed out")from bravado.exception import HTTPNotFound, HTTPUnauthorized, HTTPTooManyRequests
import time
try:
response = client.pet.getPetById(petId=1).response()
pet = response.result
except HTTPNotFound:
print("Pet does not exist")
pet = None
except HTTPUnauthorized:
print("Need to refresh authentication")
# Handle re-authentication
except HTTPTooManyRequests as e:
# Handle rate limiting
retry_after = int(e.response.headers.get('Retry-After', 60))
print(f"Rate limited, waiting {retry_after} seconds")
time.sleep(retry_after)
# Retry logic herefrom bravado.exception import HTTPBadRequest, HTTPUnprocessableEntity
try:
response = client.pet.addPet(body=new_pet_data).response()
pet = response.result
except HTTPBadRequest as e:
print("Invalid request format")
print(f"Error details: {e.response.text}")
except HTTPUnprocessableEntity as e:
print("Validation failed")
# Parse validation errors from response
errors = e.response.json().get('errors', [])
for error in errors:
print(f"Field {error['field']}: {error['message']}")from bravado.exception import HTTPServerError, BravadoTimeoutError
# Combine fallback results with specific exception handling
try:
response = client.pet.getPetById(petId=1).response(
timeout=5.0,
fallback_result={'name': 'Unknown', 'status': 'unavailable'},
exceptions_to_catch=(BravadoTimeoutError, HTTPServerError)
)
if response.metadata.is_fallback_result:
print("Using fallback data due to service issues")
# Handle degraded functionality
pet = response.result
except HTTPNotFound:
# Still handle specific client errors that shouldn't use fallback
print("Pet definitely does not exist")
pet = Noneimport logging
from bravado.exception import HTTPError
logger = logging.getLogger(__name__)
try:
response = client.pet.getPetById(petId=1).response()
pet = response.result
except HTTPError as e:
# Log detailed error information for monitoring
logger.error(
"HTTP error in getPetById",
extra={
'status_code': e.status_code,
'pet_id': 1,
'response_body': e.response.text[:1000], # Truncate for logging
'response_headers': dict(e.response.headers),
}
)
raise # Re-raise for upstream handling# Good exception handling example
from bravado.exception import (
HTTPNotFound, HTTPUnauthorized, HTTPTooManyRequests,
HTTPServerError, BravadoTimeoutError
)
import time
import random
def get_pet_with_retry(client, pet_id, max_retries=3):
for attempt in range(max_retries + 1):
try:
response = client.pet.getPetById(petId=pet_id).response(timeout=10.0)
return response.result
except HTTPNotFound:
return None # Pet doesn't exist, don't retry
except HTTPUnauthorized:
# Handle re-authentication
refresh_auth(client)
continue
except HTTPTooManyRequests as e:
if attempt < max_retries:
# Exponential backoff with jitter
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
continue
raise
except (HTTPServerError, BravadoTimeoutError) as e:
if attempt < max_retries:
# Retry transient errors
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
continue
raise
raise Exception(f"Failed to get pet {pet_id} after {max_retries} retries")Install with Tessl CLI
npx tessl i tessl/pypi-bravado