A Python wrapper for ngrok that manages its own binary, making ngrok available via a convenient Python API
—
Direct access to ngrok's CLI API and HTTP request functionality for advanced integrations and custom workflows.
Direct interface to ngrok's command-line API for advanced operations and configurations.
def api(*args, pyngrok_config=None):
"""
Run ngrok command against the API with given arguments.
Uses the local agent to run remote API requests, requires API key.
Parameters:
- *args: Arguments to pass to the ngrok api command
- pyngrok_config (PyngrokConfig, optional): Configuration override
Returns:
NgrokApiResponse: Response from executing the api command
Raises:
PyngrokNgrokError: When ngrok process exits with error
CalledProcessError: When process execution fails
"""
class NgrokApiResponse:
"""
Container for ngrok API command response.
"""
status: str # Description of the response
data: dict # Parsed API response data
@staticmethod
def from_body(body):
"""
Construct NgrokApiResponse from response body string.
Parameters:
- body (str): Response body to parse
Returns:
NgrokApiResponse: Constructed response object
"""Usage Examples:
from pyngrok import ngrok, conf
# Configure with API key for CLI API access
config = conf.PyngrokConfig(api_key="your_ngrok_api_key_here")
ngrok.set_default(config)
# Get help for API commands
help_response = ngrok.api("--help")
print(f"Status: {help_response.status}")
if help_response.data:
print(f"Data: {help_response.data}")
# Create a reserved domain
domain = "my-app.ngrok.dev"
domain_response = ngrok.api("reserved-domains", "create", "--domain", domain)
print(f"Domain creation: {domain_response.status}")
# List reserved domains
list_response = ngrok.api("reserved-domains", "list")
print(f"Domains: {list_response.data}")
# Create a Cloud Endpoint with traffic policy
endpoint_response = ngrok.api(
"endpoints", "create",
"--bindings", "public",
"--url", f"https://{domain}",
"--traffic-policy-file", "policy.yml"
)
print(f"Endpoint creation: {endpoint_response.status}")Low-level HTTP request functionality for interacting with ngrok APIs and tunneled services.
def api_request(url, method="GET", data=None, params=None, timeout=4, auth=None):
"""
Make HTTP API request to the given URL with JSON response parsing.
Parameters:
- url (str): The request URL (must start with "http")
- method (str): HTTP method ("GET", "POST", "PUT", "DELETE", etc.)
- data (dict, optional): Request body data (will be JSON-encoded)
- params (dict, optional): URL query parameters
- timeout (float): Request timeout in seconds
- auth (str, optional): Bearer token for Authorization header
Returns:
dict: Parsed JSON response data
Raises:
PyngrokSecurityError: When URL is not supported
PyngrokNgrokHTTPError: When request returns error response
PyngrokNgrokURLError: When request times out
"""Usage Examples:
from pyngrok import ngrok
# Start a tunnel to make API requests through
tunnel = ngrok.connect("8000")
print(f"Tunnel URL: {tunnel.public_url}")
# Make GET request through tunnel
try:
response = ngrok.api_request(f"{tunnel.public_url}/api/status")
print(f"Status response: {response}")
except Exception as e:
print(f"Request failed: {e}")
# Make POST request with data
post_data = {"name": "test", "value": 123}
try:
response = ngrok.api_request(
f"{tunnel.public_url}/api/data",
method="POST",
data=post_data
)
print(f"POST response: {response}")
except Exception as e:
print(f"POST request failed: {e}")
# Make request with query parameters
params = {"limit": 10, "offset": 0}
try:
response = ngrok.api_request(
f"{tunnel.public_url}/api/items",
params=params
)
print(f"Items: {response}")
except Exception as e:
print(f"Query request failed: {e}")Make requests directly to the ngrok local API for tunnel management and inspection.
Usage Examples:
from pyngrok import ngrok
# Get the ngrok process to access API URL
process = ngrok.get_ngrok_process()
api_url = process.api_url
# Get tunnel information via direct API
tunnels_response = ngrok.api_request(f"{api_url}/api/tunnels")
print(f"Active tunnels: {len(tunnels_response['tunnels'])}")
for tunnel_data in tunnels_response['tunnels']:
print(f" {tunnel_data['name']}: {tunnel_data['public_url']}")
# Get detailed tunnel information
if tunnels_response['tunnels']:
tunnel_uri = tunnels_response['tunnels'][0]['uri']
tunnel_detail = ngrok.api_request(f"{api_url}{tunnel_uri}")
print(f"Tunnel details: {tunnel_detail}")
# Get request history via API
requests_response = ngrok.api_request(f"{api_url}/api/requests/http")
print(f"Captured requests: {len(requests_response.get('requests', []))}")
# Get agent status via API
status_response = ngrok.api_request(f"{api_url}/api/status")
print(f"Agent status: {status_response.get('status', 'unknown')}")Make requests to external ngrok APIs using authentication.
Usage Examples:
from pyngrok import ngrok
# Configure API key for external API access
api_key = "your_ngrok_api_key_here"
# Get account information
try:
account_response = ngrok.api_request(
"https://api.ngrok.com/account",
auth=api_key
)
print(f"Account: {account_response}")
except Exception as e:
print(f"Account request failed: {e}")
# List domains via API
try:
domains_response = ngrok.api_request(
"https://api.ngrok.com/reserved_domains",
auth=api_key
)
print(f"Reserved domains: {domains_response}")
except Exception as e:
print(f"Domains request failed: {e}")
# Create a tunnel via API
tunnel_config = {
"addr": "http://localhost:8000",
"name": "api-created-tunnel"
}
try:
create_response = ngrok.api_request(
"https://api.ngrok.com/tunnels",
method="POST",
data=tunnel_config,
auth=api_key
)
print(f"Tunnel created: {create_response}")
except Exception as e:
print(f"Tunnel creation failed: {e}")Examples of complex API integration scenarios.
Usage Examples:
from pyngrok import ngrok, conf
import json
import time
def setup_advanced_tunnel_with_monitoring():
"""Create tunnel with comprehensive monitoring setup"""
# Configure with all necessary credentials
config = conf.PyngrokConfig(
auth_token="your_authtoken",
api_key="your_api_key",
monitor_thread=True
)
# Create tunnel with custom configuration
tunnel = ngrok.connect(
"8000",
pyngrok_config=config,
subdomain="my-monitored-app"
)
print(f"Advanced tunnel created: {tunnel.public_url}")
# Set up monitoring through API
process = ngrok.get_ngrok_process(config)
api_url = process.api_url
def monitor_tunnel_health():
"""Monitor tunnel health and performance"""
while True:
try:
# Check tunnel status
tunnel_response = ngrok.api_request(f"{api_url}{tunnel.uri}")
metrics = tunnel_response.get('metrics', {})
# Check request rate
conn_count = metrics.get('conns', {}).get('count', 0)
print(f"Active connections: {conn_count}")
# Check for errors in recent requests
requests_response = ngrok.api_request(
f"{api_url}/api/requests/http",
params={"tunnel_name": tunnel.name}
)
recent_requests = requests_response.get('requests', [])[-10:]
error_count = sum(1 for req in recent_requests
if req.get('response', {}).get('status', 0) >= 400)
if error_count > 5:
print(f"WARNING: High error rate ({error_count}/10)")
except Exception as e:
print(f"Monitoring error: {e}")
time.sleep(30) # Check every 30 seconds
# Start monitoring in background thread
import threading
monitor_thread = threading.Thread(target=monitor_tunnel_health, daemon=True)
monitor_thread.start()
return tunnel
def api_based_tunnel_management():
"""Manage multiple tunnels through API calls"""
config = conf.PyngrokConfig(api_key="your_api_key")
process = ngrok.get_ngrok_process(config)
api_url = process.api_url
# Create multiple tunnels via API
tunnel_configs = [
{"addr": "8000", "name": "web-app", "proto": "http"},
{"addr": "3000", "name": "api-server", "proto": "http"},
{"addr": "22", "name": "ssh-access", "proto": "tcp"}
]
created_tunnels = []
for tunnel_config in tunnel_configs:
try:
response = ngrok.api_request(
f"{api_url}/api/tunnels",
method="POST",
data=tunnel_config
)
created_tunnels.append(response)
print(f"Created tunnel: {response['name']} -> {response['public_url']}")
except Exception as e:
print(f"Failed to create tunnel {tunnel_config['name']}: {e}")
# Monitor all tunnels
def get_tunnel_summary():
tunnels_response = ngrok.api_request(f"{api_url}/api/tunnels")
summary = {}
for tunnel in tunnels_response['tunnels']:
metrics = tunnel.get('metrics', {})
summary[tunnel['name']] = {
'url': tunnel['public_url'],
'connections': metrics.get('conns', {}).get('count', 0),
'bytes_in': metrics.get('http', {}).get('bytes_in', 0),
'bytes_out': metrics.get('http', {}).get('bytes_out', 0)
}
return summary
# Print tunnel summary
summary = get_tunnel_summary()
print(json.dumps(summary, indent=2))
return created_tunnels
# Use the advanced integration functions
advanced_tunnel = setup_advanced_tunnel_with_monitoring()
managed_tunnels = api_based_tunnel_management()Comprehensive error handling for API integrations.
Usage Examples:
from pyngrok import ngrok
from pyngrok.exception import (
PyngrokSecurityError,
PyngrokNgrokHTTPError,
PyngrokNgrokURLError
)
def robust_api_request(url, **kwargs):
"""Make API request with comprehensive error handling"""
try:
return ngrok.api_request(url, **kwargs)
except PyngrokSecurityError as e:
print(f"Security error - invalid URL: {e}")
return None
except PyngrokNgrokHTTPError as e:
print(f"HTTP error {e.status_code}: {e.message}")
print(f"Response body: {e.body}")
# Handle specific error codes
if e.status_code == 401:
print("Authentication required - check API key")
elif e.status_code == 429:
print("Rate limited - wait before retrying")
elif e.status_code >= 500:
print("Server error - may be temporary")
return None
except PyngrokNgrokURLError as e:
print(f"Network error: {e.reason}")
print("Check network connectivity")
return None
except Exception as e:
print(f"Unexpected error: {e}")
return None
# Use robust API requests
tunnel = ngrok.connect("8000")
# Safe API request to tunnel
response = robust_api_request(f"{tunnel.public_url}/api/status")
if response:
print(f"API response: {response}")
else:
print("API request failed")
# Safe request to ngrok API
process = ngrok.get_ngrok_process()
api_response = robust_api_request(f"{process.api_url}/api/tunnels")
if api_response:
print(f"Found {len(api_response['tunnels'])} tunnels")Install with Tessl CLI
npx tessl i tessl/pypi-pyngrok