CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-bravado

Library for accessing Swagger-enabled APIs

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

response-handling.mddocs/

Response Handling

Comprehensive response processing with metadata, timing information, fallback mechanisms, and both synchronous/asynchronous response patterns. The response handling system provides rich information about HTTP requests and supports fallback results for resilient applications.

Capabilities

HttpFuture

Wrapper for HTTP client futures that provides consistent response handling across different HTTP client implementations. This is the primary interface for getting results from API operations.

class HttpFuture:
    def __init__(self, future, response_adapter, operation=None, request_config=None): ...
    def response(self, timeout: float = None, fallback_result=None, exceptions_to_catch: tuple = None) -> BravadoResponse: ...
    def result(self, timeout: float = None): ...  # DEPRECATED
    def cancel(self): ...

Parameters:

  • future: Underlying HTTP client future (FutureAdapter instance)
  • response_adapter: Adapter for converting HTTP responses
  • operation: bravado_core.operation.Operation object
  • request_config: RequestConfig instance
  • timeout (float): Timeout in seconds for the operation
  • fallback_result: Value to return if operation fails with specified exceptions
  • exceptions_to_catch (tuple): Exception types that trigger fallback behavior

Returns:

  • response(): BravadoResponse object containing result and metadata
  • result(): Direct result (deprecated, use response().result instead)

Usage Example:

from bravado.client import SwaggerClient

client = SwaggerClient.from_url('http://petstore.swagger.io/v2/swagger.json')

# Get HttpFuture from operation
future = client.pet.getPetById(petId=1)

# Get response with metadata (recommended)
response = future.response(timeout=10.0)
pet_data = response.result
status_code = response.metadata.status_code
request_time = response.metadata.elapsed_time

# With fallback result for resilience
response = future.response(
    timeout=5.0,
    fallback_result={'name': 'Unknown Pet', 'status': 'unavailable'}
)

BravadoResponse

Response object containing both the unmarshalled result and comprehensive metadata about the HTTP request and response.

class BravadoResponse:
    result: Any
    metadata: BravadoResponseMetadata
    @property
    def incoming_response(self) -> IncomingResponse: ...

Attributes:

  • result: The unmarshalled response data (could be a model object, dict, list, or primitive)
  • metadata: BravadoResponseMetadata object with timing and HTTP information

Properties:

  • incoming_response: Access to the underlying HTTP response object

Usage Example:

response = client.pet.getPetById(petId=1).response()

# Access result data
pet_name = response.result.name
pet_status = response.result.status

# Access response metadata
print(f"Status: {response.metadata.status_code}")
print(f"Request took: {response.metadata.elapsed_time:.2f}s")
print(f"Response headers: {response.metadata.headers}")

# Access raw HTTP response if needed
raw_response = response.incoming_response
raw_text = raw_response.text

BravadoResponseMetadata

HTTP response metadata containing timing information, exception details, and request configuration used.

class BravadoResponseMetadata:
    start_time: float
    request_end_time: float  
    processing_end_time: float
    handled_exception_info: tuple
    request_config: RequestConfig
    def __init__(self, incoming_response, swagger_result, start_time: float, request_end_time: float, handled_exception_info: tuple, request_config: RequestConfig): ...
    @property
    def incoming_response(self) -> IncomingResponse: ...
    @property
    def status_code(self) -> int: ...
    @property
    def headers(self) -> dict: ...
    @property
    def is_fallback_result(self) -> bool: ...
    @property
    def request_elapsed_time(self) -> float: ...
    @property
    def elapsed_time(self) -> float: ...

Attributes:

  • start_time (float): Monotonic timestamp when the future was created
  • request_end_time (float): Monotonic timestamp when HTTP response was received
  • processing_end_time (float): Monotonic timestamp when response processing ended
  • handled_exception_info (tuple): Exception information if an exception was caught during processing
  • request_config: RequestConfig instance used for the request

Properties:

  • incoming_response: Underlying HTTP response object
  • status_code (int): HTTP status code
  • headers (dict): HTTP response headers
  • is_fallback_result (bool): True if result came from fallback mechanism
  • request_elapsed_time (float): Time spent on HTTP request only
  • elapsed_time (float): Total time including response processing

Usage Example:

response = client.pet.getPetById(petId=1).response()
metadata = response.metadata

# Timing information
print(f"Request time: {metadata.request_elapsed_time:.3f}s")
print(f"Total time: {metadata.elapsed_time:.3f}s")
print(f"Processing time: {metadata.elapsed_time - metadata.request_elapsed_time:.3f}s")

# HTTP details
print(f"Status: {metadata.status_code}")
print(f"Content-Type: {metadata.headers.get('content-type')}")

# Check if fallback was used
if metadata.is_fallback_result:
    print("Response came from fallback mechanism")

FutureAdapter (Base Class)

Abstract base class for HTTP client future adapters that standardizes the interface across different HTTP libraries.

class FutureAdapter:
    timeout_errors: tuple  # Must be defined by subclasses
    connection_errors: tuple  # Must be defined by subclasses
    def result(self, timeout: float = None): ...
    def cancel(self): ...

Attributes:

  • timeout_errors (tuple): Exception types that indicate timeout errors
  • connection_errors (tuple): Exception types that indicate connection errors

Methods:

  • result(): Get the result (blocking operation)
  • cancel(): Cancel the underlying operation

Fallback Mechanisms

Bravado supports fallback results for building resilient applications that can handle service failures gracefully.

Default Fallback Exceptions

FALLBACK_EXCEPTIONS: tuple  # (BravadoTimeoutError, BravadoConnectionError, HTTPServerError)
SENTINEL: object  # Sentinel value used for fallback result detection

These exceptions will trigger fallback behavior by default. The SENTINEL value is used internally to detect when no fallback result is provided.

Using Fallback Results

from bravado.exception import BravadoTimeoutError, HTTPServerError

# Basic fallback
response = future.response(
    timeout=5.0,
    fallback_result={'error': 'Service unavailable'}
)

# Custom exception handling
response = future.response(
    timeout=10.0,
    fallback_result={'pets': []},
    exceptions_to_catch=(BravadoTimeoutError, HTTPServerError)
)

# Check if fallback was used
if response.metadata.is_fallback_result:
    print("Using fallback data due to service failure")
    # Handle degraded functionality
else:
    print("Got live data from service")
    # Normal processing

Response Processing Functions

Utility functions for processing and unmarshalling HTTP responses.

def unmarshal_response(incoming_response: IncomingResponse, operation, response_callbacks: list = None): ...
def unmarshal_response_inner(response, op): ...
def raise_on_unexpected(http_response: IncomingResponse): ...
def raise_on_expected(http_response: IncomingResponse): ...
def reraise_errors(func): ...

Parameters:

  • incoming_response: HTTP response to process
  • operation: Operation that generated the response
  • response_callbacks (list): Callback functions to execute during processing
  • http_response: HTTP response to check for errors
  • func: Function to wrap with error handling

These functions are typically used internally but can be useful for custom response processing.

Response Callbacks

You can register callbacks to be executed during response processing:

from bravado.config import RequestConfig

def log_response(response, operation_name):
    print(f"Operation {operation_name} completed with status {response.status_code}")

request_config = RequestConfig(
    response_callbacks=[
        lambda resp, op: log_response(resp, op.operation_id)
    ]
)

future = client.pet.getPetById(petId=1, _request_config=request_config)
response = future.response()

Async Response Handling

When using FidoClient, response handling integrates with Twisted's event loop:

from bravado.fido_client import FidoClient
from twisted.internet import defer

@defer.inlineCallbacks
def get_pet_async():
    http_client = FidoClient()
    client = SwaggerClient.from_url(spec_url, http_client=http_client)
    
    future = client.pet.getPetById(petId=1)
    response = yield future.response()
    
    defer.returnValue(response.result)

Performance Considerations

  • Use response() method instead of deprecated result() method
  • Consider fallback results for non-critical operations
  • Monitor timing information for performance optimization
  • Use appropriate timeout values based on your application needs
# Good: Reasonable timeout with fallback
response = future.response(
    timeout=30.0,  # 30 second timeout
    fallback_result=None  # Graceful degradation
)

# Monitor performance
if response.metadata.elapsed_time > 1.0:
    print(f"Slow response detected: {response.metadata.elapsed_time:.2f}s")

Install with Tessl CLI

npx tessl i tessl/pypi-bravado

docs

authentication.md

client-management.md

configuration.md

exception-handling.md

http-clients.md

index.md

response-handling.md

spec-loading.md

testing-utilities.md

tile.json