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

authentication.mddocs/

Authentication

Modular authentication system supporting HTTP Basic authentication, API key authentication (query parameter or header), and extensible custom authentication schemes. Authentication is applied per-host and integrates seamlessly with both synchronous and asynchronous HTTP clients.

Capabilities

Authenticator (Base Class)

Abstract base class for all authentication implementations. Provides host matching and request modification interface.

class Authenticator:
    def __init__(self, host: str): ...
    def matches(self, url: str) -> bool: ...
    def apply(self, request) -> requests.Request: ...
    def __repr__(self) -> str: ...

Parameters:

  • host (str): Hostname (including port if needed) that this authenticator applies to
  • url (str): URL to check for host matching
  • request: requests.Request object to modify with authentication

Returns:

  • matches: True if the authenticator should be applied to the given URL
  • apply: Modified request object with authentication applied

BasicAuthenticator

HTTP Basic authentication implementation. Adds Authorization header with base64-encoded credentials.

class BasicAuthenticator(Authenticator):
    def __init__(self, host: str, username: str, password: str): ...
    def apply(self, request) -> requests.Request: ...

Parameters:

  • host (str): Hostname for authentication
  • username (str): Username for basic auth
  • password (str): Password for basic auth

Usage Example:

from bravado.requests_client import BasicAuthenticator, RequestsClient
from bravado.client import SwaggerClient

# Create authenticator
auth = BasicAuthenticator('api.example.com', 'myuser', 'mypassword')

# Apply to HTTP client
http_client = RequestsClient()
http_client.set_basic_auth('api.example.com', 'myuser', 'mypassword')

# Use with SwaggerClient
client = SwaggerClient.from_url('https://api.example.com/swagger.json', 
                               http_client=http_client)

ApiKeyAuthenticator

API key authentication implementation. Supports API keys in query parameters or headers.

class ApiKeyAuthenticator(Authenticator):
    def __init__(self, host: str, api_key: str, param_name: str = 'api_key', param_in: str = 'query'): ...
    def apply(self, request) -> requests.Request: ...

Parameters:

  • host (str): Hostname for authentication
  • api_key (str): API key value
  • param_name (str): Parameter name for the API key (default: 'api_key')
  • param_in (str): Where to place the API key - 'query' or 'header' (default: 'query')

Usage Examples:

from bravado.requests_client import ApiKeyAuthenticator, RequestsClient
from bravado.client import SwaggerClient

# API key in query parameter
http_client = RequestsClient()
http_client.set_api_key('api.example.com', 'your-api-key-here', param_name='apikey')

# API key in header
http_client = RequestsClient()
http_client.set_api_key('api.example.com', 'your-api-key-here', 
                       param_name='X-API-Key', param_in='header')

# Use with SwaggerClient
client = SwaggerClient.from_url('https://api.example.com/swagger.json',
                               http_client=http_client)

RequestsClient Authentication Methods

The RequestsClient provides convenience methods for setting up authentication:

class RequestsClient:
    def set_basic_auth(self, host: str, username: str, password: str): ...
    def set_api_key(self, host: str, api_key: str, param_name: str = 'api_key', param_in: str = 'query'): ...
    def apply_authentication(self, request): ...

Parameters:

  • host (str): Hostname for authentication
  • username (str): Username for basic auth
  • password (str): Password for basic auth
  • api_key (str): API key value
  • param_name (str): Parameter name for API key
  • param_in (str): Location for API key ('query' or 'header')

These methods create and register the appropriate authenticator instances internally.

Multiple Authentication

You can configure multiple authenticators for different hosts:

from bravado.requests_client import RequestsClient

http_client = RequestsClient()

# Different auth for different services
http_client.set_basic_auth('api.service1.com', 'user1', 'pass1')
http_client.set_api_key('api.service2.com', 'key123', param_name='token', param_in='header')

# Authenticators are automatically selected based on request URL

Custom Authenticators

Create custom authentication schemes by extending the Authenticator base class:

from bravado.requests_client import Authenticator
import hmac
import hashlib
import time

class HMACAuthenticator(Authenticator):
    def __init__(self, host, key_id, secret_key):
        super().__init__(host)
        self.key_id = key_id
        self.secret_key = secret_key
    
    def apply(self, request):
        timestamp = str(int(time.time()))
        
        # Create signature
        message = f"{request.method}{request.url}{timestamp}"
        signature = hmac.new(
            self.secret_key.encode(),
            message.encode(),
            hashlib.sha256
        ).hexdigest()
        
        # Add authentication headers
        request.headers['X-Auth-Key'] = self.key_id
        request.headers['X-Auth-Timestamp'] = timestamp
        request.headers['X-Auth-Signature'] = signature
        
        return request

# Use custom authenticator
auth = HMACAuthenticator('api.example.com', 'key123', 'secret456')
http_client = RequestsClient()
# Note: Custom authenticators need to be manually added to the client's authenticators list

Authentication Debugging

When authentication fails, check the following:

  1. Host Matching: Ensure the authenticator host matches the request URL exactly
  2. Parameter Names: Verify API key parameter names match the API specification
  3. URL Structure: Check if the API expects authentication on all endpoints or specific paths
# Enable debug logging to see authentication details
import logging
logging.basicConfig(level=logging.DEBUG)

# Check if authenticator matches
auth = BasicAuthenticator('api.example.com', 'user', 'pass')
print(auth.matches('https://api.example.com/pets'))  # Should be True
print(auth.matches('https://other.example.com/pets'))  # Should be False

Security Considerations

  • HTTPS: Always use HTTPS when transmitting credentials
  • Key Storage: Store API keys and passwords securely (environment variables, key management systems)
  • Key Rotation: Implement proper key rotation practices
  • Scope Limitation: Use API keys with minimal required permissions
import os
from bravado.requests_client import RequestsClient

# Good: Load credentials from environment
http_client = RequestsClient()
http_client.set_api_key(
    'api.example.com',
    os.environ['API_KEY'],  # Never hardcode keys
    param_name='Authorization',
    param_in='header'
)

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