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

spec-loading.mddocs/

Spec Loading

Utilities for loading OpenAPI/Swagger specifications from URLs, local files, and YAML/JSON sources with support for remote references and custom headers. The spec loading system provides flexible ways to load specifications while handling various formats and sources.

Capabilities

Loader

Primary abstraction for loading Swagger/OpenAPI specifications from various sources. Handles both JSON and YAML formats, remote references, and custom request headers.

class Loader:
    def __init__(self, http_client, request_headers: dict = None): ...
    def load_spec(self, spec_url: str, base_url: str = None) -> dict: ...
    def load_yaml(self, text: str) -> dict: ...

Parameters:

  • http_client: HTTP client instance for fetching remote specs
  • request_headers (dict): Headers to include with HTTP requests when loading specs
  • spec_url (str): URL or file path to the OpenAPI specification
  • base_url (str): Base URL for resolving relative references in the spec
  • text (str): YAML text content to parse

Returns:

  • load_spec: Parsed specification as a dictionary
  • load_yaml: Parsed YAML content as a dictionary

Usage Example:

from bravado.swagger_model import Loader
from bravado.requests_client import RequestsClient

# Create loader with HTTP client
http_client = RequestsClient()
loader = Loader(http_client)

# Load from URL
spec_dict = loader.load_spec('https://petstore.swagger.io/v2/swagger.json')

# Load with custom headers
loader_with_auth = Loader(
    http_client, 
    request_headers={'Authorization': 'Bearer token123'}
)
spec_dict = loader_with_auth.load_spec('https://api.example.com/swagger.yaml')

# Load YAML from string
yaml_content = """
openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
paths: {}
"""
spec_dict = loader.load_yaml(yaml_content)

FileEventual

Adapter for loading local files with an EventualResult-like interface, supporting both synchronous and asynchronous-style access to local specification files.

class FileEventual:
    def __init__(self, path: str): ...
    def get_path(self) -> str: ...
    def wait(self, **kwargs): ...
    def result(self, *args, **kwargs): ...
    def cancel(self): ...

Nested Classes:

class FileEventual.FileResponse:
    def __init__(self, data: bytes): ...
    def json(self): ...

Parameters:

  • path (str): Path to the specification file
  • data (bytes): File content data

Methods:

  • get_path(): Get file path with .json extension added if needed
  • wait(): Load and return file contents
  • result(): Alias for wait() method
  • cancel(): No-op cancel method for interface compatibility

Usage Example:

from bravado.swagger_model import FileEventual

# Load local file
file_eventual = FileEventual('/path/to/swagger.json')
file_response = file_eventual.wait()
spec_dict = file_response.json()

# Automatic .json extension handling
file_eventual = FileEventual('/path/to/swagger')  # Will try /path/to/swagger.json
file_response = file_eventual.wait()

Utility Functions

Helper functions for loading specifications from various sources.

load_file

Load OpenAPI specification from a local file.

def load_file(spec_file: str, http_client=None) -> dict: ...

Parameters:

  • spec_file (str): Path to the specification file
  • http_client: HTTP client instance (optional, defaults to RequestsClient)

Returns:

  • Parsed specification dictionary

load_url

Load OpenAPI specification from a URL.

def load_url(spec_url: str, http_client=None, base_url: str = None) -> dict: ...

Parameters:

  • spec_url (str): URL to the specification
  • http_client: HTTP client instance (optional, defaults to RequestsClient)
  • base_url (str): Base URL for resolving relative references

Returns:

  • Parsed specification dictionary

request

Low-level function for downloading and parsing JSON from URLs.

def request(http_client, url: str, headers: dict) -> dict: ...

Parameters:

  • http_client: HTTP client instance
  • url (str): URL to request
  • headers (dict): HTTP headers to include

Returns:

  • Parsed JSON response

is_file_scheme_uri

Check if a URL uses the file:// scheme.

def is_file_scheme_uri(url: str) -> bool: ...

Parameters:

  • url (str): URL to check

Returns:

  • True if URL uses file:// scheme, False otherwise

Loading Patterns

Loading from URLs

from bravado.swagger_model import load_url
from bravado.requests_client import RequestsClient

# Simple URL loading
spec_dict = load_url('https://petstore.swagger.io/v2/swagger.json')

# With custom HTTP client
http_client = RequestsClient()
http_client.set_api_key('api.example.com', 'your-api-key')
spec_dict = load_url('https://api.example.com/swagger.json', http_client=http_client)

# With base URL for relative references
spec_dict = load_url(
    'https://api.example.com/swagger.json',
    base_url='https://api.example.com'
)

Loading from Local Files

from bravado.swagger_model import load_file

# Load JSON file
spec_dict = load_file('/path/to/swagger.json')

# Load YAML file
spec_dict = load_file('/path/to/swagger.yaml')

# File scheme URLs
spec_dict = load_file('file:///path/to/swagger.json')

Loading with Authentication

from bravado.swagger_model import Loader
from bravado.requests_client import RequestsClient

# HTTP client with authentication
http_client = RequestsClient()
http_client.set_basic_auth('api.example.com', 'username', 'password')

# Loader with custom headers
loader = Loader(
    http_client,
    request_headers={
        'User-Agent': 'MyApp/1.0',
        'Accept': 'application/json,application/yaml'
    }
)

spec_dict = loader.load_spec('https://api.example.com/swagger.json')

Loading with Fallback

from bravado.swagger_model import load_url, load_file
from bravado.exception import BravadoConnectionError

def load_spec_with_fallback(primary_url, fallback_file):
    """Load spec from URL with local file fallback."""
    try:
        return load_url(primary_url)
    except BravadoConnectionError:
        print(f"Failed to load from {primary_url}, using local fallback")
        return load_file(fallback_file)

spec_dict = load_spec_with_fallback(
    'https://api.example.com/swagger.json',
    '/local/cache/swagger.json'
)

Format Support

JSON Support

All loading functions automatically handle JSON format specifications:

# Standard JSON loading
spec_dict = load_url('https://api.example.com/swagger.json')

YAML Support

YAML specifications are automatically detected and parsed:

# YAML loading (detected by file extension or content)
spec_dict = load_url('https://api.example.com/swagger.yaml')
spec_dict = load_file('/path/to/swagger.yml')

# Direct YAML parsing
from bravado.swagger_model import Loader

loader = Loader(http_client)
yaml_content = """
openapi: 3.0.0
info:
  title: My API
  version: 1.0.0
paths:
  /pets:
    get:
      responses:
        '200':
          description: Success
"""
spec_dict = loader.load_yaml(yaml_content)

Remote References

The loading system automatically handles remote references ($ref) in specifications:

# Spec with remote references will be automatically resolved
spec_dict = load_url('https://api.example.com/swagger.json')

# Custom headers are passed to remote reference requests
loader = Loader(
    http_client,
    request_headers={'Authorization': 'Bearer token123'}
)
spec_dict = loader.load_spec('https://api.example.com/swagger.json')
# Authorization header will be used for any remote $ref requests

Error Handling

from bravado.swagger_model import load_url, load_file
from bravado.exception import BravadoConnectionError, HTTPNotFound
import yaml

def safe_load_spec(spec_source):
    """Safely load specification with comprehensive error handling."""
    try:
        if spec_source.startswith('http'):
            return load_url(spec_source)
        else:
            return load_file(spec_source)
            
    except HTTPNotFound:
        raise ValueError(f"Specification not found: {spec_source}")
        
    except BravadoConnectionError as e:
        raise ValueError(f"Cannot connect to load spec: {e}")
        
    except yaml.YAMLError as e:
        raise ValueError(f"Invalid YAML in specification: {e}")
        
    except Exception as e:
        raise ValueError(f"Failed to load specification: {e}")

# Usage with error handling
try:
    spec_dict = safe_load_spec('https://api.example.com/swagger.yaml')
except ValueError as e:
    print(f"Error loading spec: {e}")
    # Handle error appropriately

Performance Considerations

Caching Loaded Specs

import json
import os
from hashlib import md5
from bravado.swagger_model import load_url

class SpecCache:
    def __init__(self, cache_dir='/tmp/swagger_cache'):
        self.cache_dir = cache_dir
        os.makedirs(cache_dir, exist_ok=True)
    
    def get_cache_path(self, url):
        url_hash = md5(url.encode()).hexdigest()
        return os.path.join(self.cache_dir, f'{url_hash}.json')
    
    def load_cached_or_fetch(self, url):
        cache_path = self.get_cache_path(url)
        
        if os.path.exists(cache_path):
            with open(cache_path, 'r') as f:
                return json.load(f)
        
        # Cache miss, fetch and cache
        spec_dict = load_url(url)
        with open(cache_path, 'w') as f:
            json.dump(spec_dict, f)
        
        return spec_dict

# Usage
cache = SpecCache()
spec_dict = cache.load_cached_or_fetch('https://api.example.com/swagger.json')

Async Loading (with FidoClient)

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

@defer.inlineCallbacks
def load_spec_async(spec_url):
    """Load specification asynchronously using FidoClient."""
    http_client = FidoClient()
    loader = Loader(http_client)
    
    spec_dict = yield loader.load_spec(spec_url)
    defer.returnValue(spec_dict)

# Usage in Twisted application
def handle_spec_loaded(spec_dict):
    print(f"Loaded spec with {len(spec_dict.get('paths', {}))} paths")

d = load_spec_async('https://api.example.com/swagger.json')
d.addCallback(handle_spec_loaded)

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