InProcessTaskApp utility enables running task apps entirely within your Python script, eliminating the need for separate terminal processes or manual tunnel management. It automatically starts a FastAPI server, opens a tunnel (SynthTunnel by default, Cloudflare optional), and provides the tunnel URL for GEPA optimization jobs.
In-process task apps are designed for production workflows that run GEPA or eval
on the fly, where you want the task app lifecycle to be managed inside the same
service or worker that triggers the job.
Quick Start
Features
Automatic Server Management
Starts uvicorn server in background thread
Automatic Tunnel Creation
Opens SynthTunnel by default (Cloudflare optional)
Port Conflict Handling
Automatically finds available ports if requested port is busy
Signal Handling
Graceful shutdown on SIGINT/SIGTERM
Observability
Structured logging and optional callbacks
Multiple Input Methods
Supports app, config, config_factory, or file path
API Reference
InProcessTaskApp
Context manager for running task apps in-process with automatic tunneling.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
app | Optional[ASGIApplication] | None | FastAPI app instance (most direct) |
config | Optional[TaskAppConfig] | None | TaskAppConfig object |
config_factory | Optional[Callable[[], TaskAppConfig]] | None | Callable that returns TaskAppConfig |
task_app_path | Optional[Path | str] | None | Path to task app .py file (fallback) |
port | int | 8114 | Local port to run server on (must be in range [1024, 65535]) |
host | str | "127.0.0.1" | Host to bind to (must be localhost for security) |
tunnel_mode | str | "synthtunnel" | Tunnel mode (“synthtunnel”, “quick”, “named”, “local”, “preconfigured”) |
tunnel_backend | Optional[TunnelBackend | str] | None | Explicit tunnel backend (overrides tunnel_mode) |
preconfigured_url | Optional[str] | None | External URL when tunnel_mode="preconfigured" |
preconfigured_auth_header | Optional[str] | None | Auth header name for preconfigured URL |
preconfigured_auth_token | Optional[str] | None | Auth token value for preconfigured URL |
api_key | Optional[str] | None | API key for health checks (defaults to ENVIRONMENT_API_KEY env var) |
health_check_timeout | float | 30.0 | Max time to wait for health check in seconds |
auto_find_port | bool | True | Automatically find available port if requested port is busy |
skip_tunnel_verification | bool | True | Skip HTTP verification of tunnel connectivity |
force_new_tunnel | bool | False | Force a fresh managed tunnel (Cloudflare managed only) |
on_start | Optional[Callable[[InProcessTaskApp], None]] | None | Callback called when task app starts |
on_stop | Optional[Callable[[InProcessTaskApp], None]] | None | Callback called when task app stops |
Attributes
url(Optional[str]): The public tunnel URL (available after__aenter__)port(int): The actual port the server is running on (may differ from requested ifauto_find_port=True)host(str): The host the server is bound totunnel_mode(str): The tunnel mode being usedtask_app_worker_token(Optional[str]): SynthTunnel worker token (only set for SynthTunnel)
Raises
ValueError: If multiple or no input methods provided, or invalid parametersFileNotFoundError: Iftask_app_pathdoesn’t existRuntimeError: If health check fails or port conflicts can’t be resolved
Usage Examples
Exactly one of
app, config, config_factory, or task_app_path must be provided.1. Direct FastAPI App (app)
2. TaskAppConfig Object (config)
3. Config Factory (config_factory) — Recommended
4. File Path (task_app_path)
With Callbacks and Custom Port
Full GEPA Integration
If you’re using SynthTunnel, ensure the job is configured with
task_app_worker_token (the SDK can wire this automatically when using
run_in_process_job).Port Conflict Handling
The utility automatically handles port conflicts:auto_find_port=True(default): If requested port is busy, automatically finds next available portauto_find_port=False: Attempts to kill process on port, then raises error if still busy
Input Validation
The utility validates all inputs with clear error messages:- Port: Must be in range [1024, 65535]
- Host: Must be
127.0.0.1,localhost, or0.0.0.0(security requirement) - Tunnel Mode:
"synthtunnel","quick","named","local", or"preconfigured" - Task App Path: Must exist and be a
.pyfile - Input Methods: Exactly one of
app,config,config_factory, ortask_app_pathmust be provided
Logging
The utility uses Python’slogging module:
- INFO: Major lifecycle events (start, stop, tunnel URL)
- DEBUG: Detailed operations (port checks, health checks)
- WARNING: Port conflicts, callback exceptions
Signal Handling
The utility automatically handles SIGINT/SIGTERM signals for graceful shutdown:- All active instances are cleaned up on signal
- Prevents orphaned processes
- Works seamlessly with context manager cleanup
Requirements
- Python >= 3.11
- SynthTunnel (default) requires
SYNTH_API_KEY cloudflaredbinary only if using Cloudflare tunnels (tunnel_backend="cloudflare_quick")- Task app must expose
/healthendpoint - Task app must accept
X-API-Keyheader for authentication
Troubleshooting
Port Already in Use
If you see “address already in use” errors:Health Check Timeout
If health check times out:- Verify task app has
/healthendpoint - Verify task app accepts
X-API-Keyheader - Increase timeout:
health_check_timeout=60.0
Tunnel Not Opening
If tunnel fails to open:- If using SynthTunnel, confirm
SYNTH_API_KEYis set - If using Cloudflare, verify
cloudflaredis installed:which cloudflared - Check network connectivity
- Review logs for detailed error messages