CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyngrok

A Python wrapper for ngrok that manages its own binary, making ngrok available via a convenient Python API

Pending
Overview
Eval results
Files

agent-inspection.mddocs/

Agent and Request Inspection

HTTP request capture and inspection functionality for debugging and replaying requests through ngrok tunnels with full request/response details.

Capabilities

Agent Status Information

Container for ngrok agent status and session information.

class NgrokAgent:
    """
    Container for ngrok agent information.
    """
    data: dict          # Original agent data from ngrok
    status: str         # Status of the agent
    agent_version: str  # Version of the ngrok agent
    session: dict       # Session details for the agent
    uri: str           # URI of the agent

Request Capture Information

Container for captured HTTP requests through ngrok tunnels.

class CapturedRequest:
    """
    Container for captured HTTP request from ngrok tunnel.
    """
    data: dict          # Original request data from ngrok
    id: str            # ID of the captured request
    uri: str           # URI of the captured request
    tunnel_name: str   # Name of tunnel that captured the request
    remote_addr: str   # Remote address of the request
    start: str         # Start time of the request
    duration: int      # Duration of the request in milliseconds
    request: dict      # Request details (method, headers, body, etc.)
    response: dict     # Response details (status, headers, body, etc.)

Getting Agent Status

Retrieve current ngrok agent status and session information.

def get_agent_status(pyngrok_config=None):
    """
    Get the ngrok agent status.

    Parameters:
    - pyngrok_config (PyngrokConfig, optional): Configuration override

    Returns:
    NgrokAgent: The agent status information
    """

Usage Examples:

from pyngrok import agent, ngrok

# Start a tunnel first to have an active agent
tunnel = ngrok.connect("8000")

# Get agent status
agent_status = agent.get_agent_status()
print(f"Agent status: {agent_status.status}")
print(f"Agent version: {agent_status.agent_version}")
print(f"Agent URI: {agent_status.uri}")

# Access raw agent data
print(f"Session info: {agent_status.session}")

Listing Captured Requests

Retrieve HTTP requests that have been captured by ngrok tunnels.

def get_requests(tunnel_name=None, pyngrok_config=None):
    """
    Get list of requests made to tunnels.

    Parameters:
    - tunnel_name (str, optional): Filter by specific tunnel name
    - pyngrok_config (PyngrokConfig, optional): Configuration override

    Returns:
    list[CapturedRequest]: List of captured request objects
    """

Usage Examples:

from pyngrok import agent, ngrok
import requests
import time

# Create a tunnel
tunnel = ngrok.connect("8000")
print(f"Send requests to: {tunnel.public_url}")

# Make some HTTP requests to generate captured data
# (In real usage, external services would make these requests)
time.sleep(1)  # Allow tunnel to be ready

# Get all captured requests
all_requests = agent.get_requests()
print(f"Total requests captured: {len(all_requests)}")

for req in all_requests[-5:]:  # Last 5 requests
    print(f"Request ID: {req.id}")
    print(f"From: {req.remote_addr}")
    print(f"Method: {req.request.get('method', 'Unknown')}")
    print(f"Path: {req.request.get('uri', 'Unknown')}")
    print(f"Duration: {req.duration}ms")
    print("---")

# Get requests for specific tunnel
tunnel_requests = agent.get_requests(tunnel_name=tunnel.name)
print(f"Requests for {tunnel.name}: {len(tunnel_requests)}")

Getting Specific Request

Retrieve detailed information about a specific captured request.

def get_request(request_id, pyngrok_config=None):
    """
    Get details for a specific captured request.

    Parameters:
    - request_id (str): ID of the request to fetch
    - pyngrok_config (PyngrokConfig, optional): Configuration override

    Returns:
    CapturedRequest: The detailed request information
    """

Usage Examples:

from pyngrok import agent, ngrok

# Create tunnel and get some requests
tunnel = ngrok.connect("8000")
requests_list = agent.get_requests()

if requests_list:
    # Get detailed info for first request
    request_id = requests_list[0].id
    detailed_request = agent.get_request(request_id)
    
    print(f"Request ID: {detailed_request.id}")
    print(f"Tunnel: {detailed_request.tunnel_name}")
    print(f"Start time: {detailed_request.start}")
    print(f"Duration: {detailed_request.duration}ms")
    
    # Access detailed request information
    request_info = detailed_request.request
    print(f"Method: {request_info.get('method')}")
    print(f"URI: {request_info.get('uri')}")
    print(f"Headers: {request_info.get('headers', {})}")
    
    # Access response information
    response_info = detailed_request.response
    if response_info:
        print(f"Status: {response_info.get('status')}")
        print(f"Response headers: {response_info.get('headers', {})}")

Replaying Requests

Replay captured requests through ngrok tunnels for testing and debugging.

def replay_request(request_id, tunnel_name=None, pyngrok_config=None):
    """
    Replay a captured request through its original or different tunnel.

    Parameters:
    - request_id (str): ID of the request to replay
    - tunnel_name (str, optional): Name of tunnel to replay through
    - pyngrok_config (PyngrokConfig, optional): Configuration override
    """

Usage Examples:

from pyngrok import agent, ngrok

# Create tunnels
tunnel1 = ngrok.connect("8000")
tunnel2 = ngrok.connect("9000")

# Get captured requests
requests_list = agent.get_requests()

if requests_list:
    request_id = requests_list[0].id
    
    # Replay through original tunnel
    print(f"Replaying request {request_id} through original tunnel")
    agent.replay_request(request_id)
    
    # Replay through different tunnel
    print(f"Replaying request {request_id} through {tunnel2.name}")
    agent.replay_request(request_id, tunnel_name=tunnel2.name)

Clearing Request History

Remove captured request history from ngrok.

def delete_requests(pyngrok_config=None):
    """
    Delete all captured request history.

    Parameters:
    - pyngrok_config (PyngrokConfig, optional): Configuration override
    """

Usage Examples:

from pyngrok import agent, ngrok

# Create tunnel and generate some requests
tunnel = ngrok.connect("8000")

# Check current request count
requests_before = agent.get_requests()
print(f"Requests before cleanup: {len(requests_before)}")

# Clear all request history
agent.delete_requests()

# Verify cleanup
requests_after = agent.get_requests()
print(f"Requests after cleanup: {len(requests_after)}")  # Should be 0

Advanced Request Analysis

Examples of analyzing captured request data for debugging and monitoring.

Usage Examples:

from pyngrok import agent, ngrok
from collections import Counter
import json

# Create tunnel for analysis
tunnel = ngrok.connect("8000")
print(f"Analyze requests at: {tunnel.public_url}")

# Wait for some requests to be made...
# Then analyze the captured data

requests_list = agent.get_requests()

# Analyze request patterns
if requests_list:
    # Count requests by method
    methods = [req.request.get('method', 'Unknown') for req in requests_list]
    method_counts = Counter(methods)
    print(f"Request methods: {dict(method_counts)}")
    
    # Count requests by path
    paths = [req.request.get('uri', 'Unknown') for req in requests_list]
    path_counts = Counter(paths)
    print(f"Popular paths: {dict(path_counts)}")
    
    # Analyze response times
    durations = [req.duration for req in requests_list if req.duration]
    if durations:
        avg_duration = sum(durations) / len(durations)
        max_duration = max(durations)
        print(f"Average response time: {avg_duration:.2f}ms")
        print(f"Max response time: {max_duration}ms")
    
    # Find errors
    error_requests = []
    for req in requests_list:
        if req.response:
            status = req.response.get('status', 0)
            if status >= 400:
                error_requests.append(req)
    
    print(f"Error requests: {len(error_requests)}")
    for error_req in error_requests[-3:]:  # Last 3 errors
        status = error_req.response.get('status')
        path = error_req.request.get('uri')
        print(f"  {status} error on {path}")

# Export request data for external analysis
def export_requests_to_json(filename):
    requests_list = agent.get_requests()
    export_data = []
    for req in requests_list:
        export_data.append({
            'id': req.id,
            'tunnel_name': req.tunnel_name,
            'remote_addr': req.remote_addr,
            'start': req.start,
            'duration': req.duration,
            'request': req.request,
            'response': req.response
        })
    
    with open(filename, 'w') as f:
        json.dump(export_data, f, indent=2)
    print(f"Exported {len(export_data)} requests to {filename}")

# Export current requests
export_requests_to_json("ngrok_requests.json")

Monitoring and Alerting

Set up monitoring based on captured request patterns.

Usage Examples:

from pyngrok import agent, ngrok
import time
import threading

def monitor_requests(tunnel_name, alert_threshold=10):
    """Monitor request rate and alert on high traffic"""
    last_count = 0
    
    while True:
        current_requests = agent.get_requests(tunnel_name=tunnel_name)
        current_count = len(current_requests)
        
        requests_per_minute = current_count - last_count
        if requests_per_minute > alert_threshold:
            print(f"ALERT: High traffic detected! {requests_per_minute} requests/minute")
            
            # Analyze recent requests
            recent_requests = current_requests[-requests_per_minute:]
            error_count = sum(1 for req in recent_requests 
                            if req.response and req.response.get('status', 0) >= 400)
            print(f"  Error rate: {error_count}/{requests_per_minute}")
        
        last_count = current_count
        time.sleep(60)  # Check every minute

# Start tunnel and monitoring
tunnel = ngrok.connect("8000")
monitor_thread = threading.Thread(
    target=monitor_requests, 
    args=(tunnel.name, 5),  # Alert if >5 requests/minute
    daemon=True
)
monitor_thread.start()

print(f"Monitoring traffic to {tunnel.public_url}")
print("Send requests to trigger monitoring...")

Install with Tessl CLI

npx tessl i tessl/pypi-pyngrok

docs

agent-inspection.md

api-integration.md

configuration.md

index.md

installation.md

process-management.md

tunnel-management.md

tile.json