CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-hypercorn

A high-performance ASGI and WSGI web server implementation that provides comprehensive support for modern web protocols including HTTP/1, HTTP/2, WebSockets, and experimental HTTP/3

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

application-wrappers.mddocs/

Application Wrappers

Wrapper classes that adapt ASGI and WSGI applications to Hypercorn's internal protocol interface. These wrappers handle protocol translation, request/response lifecycle management, and provide the bridge between applications and Hypercorn's event-driven architecture.

Capabilities

ASGI Application Wrapper

Wrapper for ASGI applications that provides the interface between ASGI applications and Hypercorn's internal protocol handling.

class ASGIWrapper:
    """
    Wrapper for ASGI applications.
    
    Adapts ASGI applications to Hypercorn's internal protocol interface,
    handling the ASGI application lifecycle and providing the necessary
    sync_spawn and call_soon capabilities for ASGI compatibility.
    """
    
    def __init__(self, app: ASGIFramework):
        """
        Initialize ASGI wrapper.
        
        Args:
            app: ASGI application callable that follows the ASGI spec
        """
        
    async def __call__(
        self, 
        scope: Scope,
        receive: ASGIReceiveCallable,
        send: ASGISendCallable,
        sync_spawn: Callable,
        call_soon: Callable
    ):
        """
        Execute the ASGI application.
        
        Args:
            scope: ASGI scope dictionary containing request information
            receive: ASGI receive callable for getting request data
            send: ASGI send callable for sending response data  
            sync_spawn: Function to spawn synchronous tasks
            call_soon: Function to schedule tasks for immediate execution
            
        The wrapper handles the ASGI application lifecycle, managing
        the connection between Hypercorn's event-driven architecture
        and the ASGI application interface.
        """

WSGI Application Wrapper

Wrapper for WSGI applications that adapts them to work within Hypercorn's async environment, handling the synchronous WSGI interface within an async context.

class WSGIWrapper:
    """
    Wrapper for WSGI applications.
    
    Adapts WSGI applications to work within Hypercorn's async environment
    by handling the synchronous WSGI interface and translating between
    WSGI's request/response model and ASGI's event-driven interface.
    """
    
    def __init__(self, app: WSGIFramework, max_body_size: int):
        """
        Initialize WSGI wrapper.
        
        Args:
            app: WSGI application callable following WSGI spec
            max_body_size: Maximum request body size in bytes
        """
        
    async def __call__(
        self,
        scope: Scope,
        receive: ASGIReceiveCallable, 
        send: ASGISendCallable,
        sync_spawn: Callable,
        call_soon: Callable
    ):
        """
        Execute the WSGI application.
        
        Args:
            scope: ASGI scope dictionary (converted to WSGI environ)
            receive: ASGI receive callable for getting request data
            send: ASGI send callable for sending response data
            sync_spawn: Function to spawn synchronous tasks (used for WSGI execution)
            call_soon: Function to schedule tasks for immediate execution
            
        The wrapper translates between ASGI's async event model and
        WSGI's synchronous request/response model, handling:
        - Environ dictionary creation from ASGI scope
        - Request body streaming and buffering  
        - Response handling and chunked encoding
        - Synchronous execution within async context
        """

Application Loading Exceptions

Exceptions raised during application loading and wrapping processes.

class InvalidPathError(Exception):
    """
    Raised when an invalid application path is provided.
    
    This exception occurs when the application path cannot be
    resolved to a valid ASGI or WSGI application, such as:
    - Module import failures
    - Missing application attributes
    - Invalid application callable signatures
    """

Framework Type Definitions

Type definitions for the application frameworks supported by the wrappers.

# ASGI application interface
ASGIFramework = Callable[[Scope, ASGIReceiveCallable, ASGISendCallable], Awaitable[None]]

# WSGI application interface
WSGIFramework = Callable[[dict, Callable], Iterable[bytes]]

# ASGI scope types
Scope = HTTPScope | WebsocketScope | LifespanScope

# ASGI callable types
ASGIReceiveCallable = Callable[[], Awaitable[ASGIReceiveEvent]]
ASGISendCallable = Callable[[ASGISendEvent], Awaitable[None]]

Usage Examples

Direct ASGI Wrapper Usage

from hypercorn.app_wrappers import ASGIWrapper

async def asgi_app(scope, receive, send):
    """Simple ASGI application"""
    if scope['type'] == 'http':
        await send({
            'type': 'http.response.start',
            'status': 200,
            'headers': [[b'content-type', b'text/plain']],
        })
        await send({
            'type': 'http.response.body',
            'body': b'Hello from ASGI',
        })

# Wrap the ASGI application
wrapper = ASGIWrapper(asgi_app)

# The wrapper is now ready for use by Hypercorn's internal protocol handlers

Direct WSGI Wrapper Usage

from hypercorn.app_wrappers import WSGIWrapper

def wsgi_app(environ, start_response):
    """Simple WSGI application"""
    status = '200 OK'
    headers = [('Content-Type', 'text/plain')]
    start_response(status, headers)
    return [b'Hello from WSGI']

# Wrap the WSGI application with body size limit
max_body_size = 16 * 1024 * 1024  # 16MB
wrapper = WSGIWrapper(wsgi_app, max_body_size)

# The wrapper is now ready for use by Hypercorn's internal protocol handlers

Framework Detection and Wrapping

The wrappers are typically used internally by Hypercorn, but can be used directly for custom server implementations:

from hypercorn.app_wrappers import ASGIWrapper, WSGIWrapper
from hypercorn.utils import is_asgi

def wrap_application(app, max_body_size=16*1024*1024):
    """Wrap application based on its type"""
    if is_asgi(app):
        return ASGIWrapper(app)
    else:
        return WSGIWrapper(app, max_body_size)

# Usage
wrapped_app = wrap_application(my_app)

Custom Application Wrapper

For advanced use cases, you can create custom wrappers following the same interface:

class CustomWrapper:
    def __init__(self, app):
        self.app = app
        
    async def __call__(self, scope, receive, send, sync_spawn, call_soon):
        # Custom application adaptation logic
        if scope['type'] == 'http':
            # Handle HTTP requests
            await self.handle_http(scope, receive, send)
        elif scope['type'] == 'websocket':
            # Handle WebSocket connections
            await self.handle_websocket(scope, receive, send)
            
    async def handle_http(self, scope, receive, send):
        # Custom HTTP handling
        pass
        
    async def handle_websocket(self, scope, receive, send):
        # Custom WebSocket handling  
        pass

Error Handling

from hypercorn.app_wrappers import InvalidPathError, WSGIWrapper

try:
    wrapper = WSGIWrapper(invalid_app, 1024*1024)
except InvalidPathError as e:
    print(f"Failed to wrap application: {e}")
    # Handle invalid application path

The application wrappers provide the essential bridge between standard Python web frameworks (ASGI/WSGI) and Hypercorn's high-performance async server architecture, enabling seamless integration of existing applications with modern protocol support.

Install with Tessl CLI

npx tessl i tessl/pypi-hypercorn

docs

application-wrappers.md

async-integration.md

configuration.md

events.md

index.md

logging.md

middleware.md

server-execution.md

types.md

utilities.md

tile.json