Python Bindings
Async Python bindings via PyO3 with full type hints.
Table of contents
- Installation
- Quick Start
- Session Manager
- Context Manager
- Interactive Shell
- Multiple Sessions
- Session Types
- Type Hints
Installation
pip install aws-ssm-bridge
Quick Start
import asyncio
from aws_ssm_bridge import SessionManager
async def main():
# Create session manager
manager = await SessionManager.new()
# Use context manager for automatic cleanup
async with await manager.start_session(target="i-0123456789abcdef0") as session:
await session.send(b"whoami\n")
async for chunk in await session.output():
print(chunk.decode(), end="")
asyncio.run(main())
Session Manager
The SessionManager handles AWS authentication and session lifecycle:
import asyncio
from aws_ssm_bridge import SessionManager
async def main():
# Create manager (loads AWS credentials from default chain)
manager = await SessionManager.new()
# Start session with options
session = await manager.start_session(
target="i-0123456789abcdef0",
region="us-west-2", # Optional
session_type="standard_stream", # Optional
reason="Debugging issue #123", # Optional (for audit)
)
# Wait for session to be ready
if await session.wait_for_ready(timeout_secs=30.0):
await session.send(b"hostname\n")
async for chunk in await session.output():
print(chunk.decode(), end="")
# Always terminate when done
await session.terminate()
asyncio.run(main())
Context Manager
Use the async context manager for automatic cleanup:
async with await manager.start_session(target="i-xxx") as session:
await session.send(b"ls -la\n")
async for chunk in await session.output():
print(chunk.decode(), end="")
# Session automatically terminated on exit
Interactive Shell
Full terminal support with raw mode, resize, and signal handling:
import asyncio
from aws_ssm_bridge import InteractiveShell, InteractiveConfig, run_shell
async def main():
# Option 1: Quick one-liner
await run_shell("i-0123456789abcdef0")
# Option 2: Full control
config = InteractiveConfig(
show_banner=True,
send_initial_size=True,
forward_signals=True,
)
shell = InteractiveShell(config)
await shell.connect("i-0123456789abcdef0")
await shell.run() # Blocks until Ctrl+D
asyncio.run(main())
Features:
- Raw terminal mode (no echo, immediate input)
- Terminal resize detection (SIGWINCH)
- Signal forwarding (Ctrl+C, Ctrl+D, Ctrl+Z)
- Automatic terminal restoration on exit/crash
Multiple Sessions
Run commands on multiple instances concurrently:
import asyncio
from aws_ssm_bridge import SessionManager
async def run_command(manager, instance_id: str, command: str) -> str:
async with await manager.start_session(target=instance_id) as session:
await session.send(f"{command}\n".encode())
output = []
async for chunk in await session.output():
output.append(chunk.decode())
if len(output) > 10:
break
return "".join(output)
async def main():
manager = await SessionManager.new()
instances = ["i-aaa", "i-bbb", "i-ccc"]
results = await asyncio.gather(*[
run_command(manager, i, "hostname") for i in instances
], return_exceptions=True)
for inst, result in zip(instances, results):
if isinstance(result, Exception):
print(f"{inst}: ERROR - {result}")
else:
print(f"{inst}: {result.strip()}")
asyncio.run(main())
Session Types
AWS SSM Session Manager supports 3 session types:
# Shell session (default) - standard interactive shell
shell = await manager.start_session(
target="i-xxx",
session_type="standard_stream",
)
# Port forwarding session (AWS-StartPortForwardingSession)
port = await manager.start_session(
target="i-xxx",
session_type="port",
parameters={"portNumber": ["3306"], "localPortNumber": ["13306"]},
)
# Interactive commands (AWS-StartInteractiveCommand)
cmd = await manager.start_session(
target="i-xxx",
session_type="interactive_commands",
parameters={"command": ["top"]},
)
For custom documents like AWS-StartSSHSession or AWS-StartPortForwardingSessionToRemoteHost:
# SSH over Session Manager
ssh = await manager.start_session(
target="i-xxx",
document_name="AWS-StartSSHSession",
parameters={"portNumber": ["22"]},
)
# Port forward through bastion to RDS
rds = await manager.start_session(
target="i-bastion",
document_name="AWS-StartPortForwardingSessionToRemoteHost",
parameters={
"host": ["mydb.cluster-xxx.us-east-1.rds.amazonaws.com"],
"portNumber": ["3306"],
"localPortNumber": ["13306"],
},
)
Type Hints
Full .pyi stubs are included for IDE autocomplete:
from aws_ssm_bridge import SessionManager, Session, OutputStream
async def example(manager: SessionManager) -> None:
session: Session = await manager.start_session(target="i-xxx")
stream: OutputStream = await session.output()
async for chunk in stream:
data: bytes = chunk
print(data.decode())