Skip to content

SDK guide · Install, configure & best practices

From pip install to production—the complete iEDA Agent SDK guide covering install, connection management, error handling, and production best practices.

iMapsynthesisiFPfloorplaniPDNpoweriPLplacementiCTSclockiTOoptimizationiRTroutingiSTAtimingAiEDAdesign dataiPCLlayout modeliMapsynthesisiFPfloorplaniPDNpoweriPLplacementiCTSclockiTOoptimizationiRTroutingiSTAtimingAiEDAdesign dataiPCLlayout model

Installation

SDK requires Python 3.10+. Install latest via pip.

pip install ieda-agent-sdk

# Verify installation
python -c "import ieda; print(ieda.__version__)"
# Output: 0.2.0

# Install with optional dependencies
pip install ieda-agent-sdk[dev]      # Development tools: pytest, mypy, ruff
pip install ieda-agent-sdk[tracing]  # Performance tracing support
pip install ieda-agent-sdk[all]      # Everything

Configuration

Configure via env vars, config file, or code init. Priority: code params > env vars > config file.

Environment variables

# Required
export IEDA_HOST=localhost          # iEDA Platform address
export IEDA_PORT=9090              # Interface gateway port

# Optional
export IEDA_PROTOCOL=python        # Default protocol: python | mcp | tcl
export IEDA_TIMEOUT_MS=30000       # Default timeout (ms)
export IEDA_TRACING=false          # Enable performance tracing
export IEDA_MAX_RETRIES=3          # Default retry count
export IEDA_LOG_LEVEL=INFO         # Log level: DEBUG | INFO | WARN | ERROR

Config file

# ~/.ieda/config.yaml
host: localhost
port: 9090
protocol: python
timeout_ms: 30000
tracing: false
max_retries: 3
log_level: INFO
connection:
  pool_size: 4
  keepalive_sec: 60
  reconnect_delay_ms: 1000

Connection settings

from ieda import AgentClient

# Minimal configuration
client = AgentClient()
client.connect()

# Full configuration
client = AgentClient(
    host="ieda-platform.local",
    port=9090,
    protocol="python",
    timeout_ms=60000,
    tracing=True,
    log_level="DEBUG",
    connection_pool_size=8,
    keepalive_sec=30,
)
client.connect()
assert client.is_connected()

Error handling

SDK defines layered exceptions—from network to tool layer—each with clear meaning and recovery guidance.

Exception hierarchy

IEDAError                    # Base exception
├── ConnectionError          # Network: cannot connect / disconnected
│   ├── ConnectionRefused
│   └── ConnectionTimeout
├── ValidationError           # Params: schema validation failed
│   ├── MissingField
│   ├── InvalidType
│   └── OutOfRange
├── ToolError                 # Tool layer: execution failed
│   ├── ToolNotFound
│   └── ToolExecutionError
├── TimeoutError              # Timeout
├── GateFailure               # Gate: evaluation gate failed
├── CASConflict               # Concurrency: CAS commit conflict
└── RateLimitError            # Rate limit exceeded

Retry strategy

from ieda import retry, RetryConfig

# Built-in retry with exponential backoff
result = retry(
    lambda: client.call("iSTA.analyze", snap=snap.id),
    config=RetryConfig(
        max_attempts=3,
        backoff_ms=1000,
        backoff_multiplier=2.0,
        max_backoff_ms=30000,
        retry_on={TimeoutError, ConnectionError},
    ),
)

# Manual retry with CAS conflict handling
for attempt in range(3):
    try:
        result = client.call("iDB.commit", expected_head=head, proposal=prop)
        break
    except CASConflict as e:
        print(f"Rebasing to {e.conflict_with} (attempt {attempt+1})")
        prop = rebase_proposal(prop, e.conflict_with)

Degraded mode

# Graceful degradation when a tool is unavailable
try:
    timing = client.call("iSTA.analyze", snap=snap.id)
except ToolNotFound:
    logging.warning("iSTA not available — falling back to basic timing")
    timing = basic_timing_estimate(design)
except RateLimitError:
    logging.warning("Rate limited — using cached result")
    timing = cache.get("timing", snap.id)

Best practices

Batch operations

# Avoid: N individual calls
for cell in critical_cells:
    result = client.call("iDB.inspect", cell_id=cell.id)  # Latency adds up

# Prefer: single batch call
results = client.call("iDB.batch_inspect", cell_ids=[c.id for c in critical_cells])

Result caching

from ieda import cached_call

# Cache snapshot-based results — same snap = same result
timing = cached_call(
    client, "iSTA.analyze",
    snap=snap.id,
    ttl_sec=300,  # Cache for 5 minutes
)

Connection pool reuse

# Production setup — reuse connection pool
client = AgentClient(connection_pool_size=8)
client.connect()

# Use context manager for automatic cleanup
with AgentClient(connection_pool_size=4) as client:
    design = client.load_design("aes_core", tech="sky130")
    result = client.call("iPL.place", design=design)
# Connection pool automatically closed

Graceful shutdown

import signal

client = AgentClient()
client.connect()

def shutdown(signum, frame):
    print("Shutting down...")
    client.disconnect()
    print("Disconnected.")

signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)

Health check

# Periodic health check in long-running agents
def ensure_connected(client: AgentClient):
    if not client.is_connected():
        logging.warning("Connection lost — reconnecting...")
        client.connect()
    health = client.health_check()
    if not health.ok:
        raise ConnectionError(f"Platform unhealthy: {health.message}")

SDK ready—start building your Agent

See API reference for endpoint details, or jump to Quickstart.