Netmiko Fundamentals
Connecting to a Device with Netmiko
What you'll learn
- How to open a connection with ConnectHandler and close it with disconnect()
- Two safe ways to supply credentials at runtime: getpass() and environment variables
- The two exceptions a connection attempt can raise, and what each one means
- Why a connection should always be closed, not just left open
- How this maps onto the connection/check function this module is building toward
Listen to a guided explanation of this lesson.
Spoken narration isn't supported in this browser.
Opening a connection
ConnectHandler is the function that actually opens the SSH session. It takes the connection parameters from the last lesson and returns a connection object you can run commands on:
from netmiko import ConnectHandler
device = {
"device_type": "cisco_ios",
"host": "192.168.1.1", # placeholder — use your own lab device's IP
"username": "labuser", # placeholder — never a real credential
"password": "labpass", # placeholder — see the next section for the real way to do this
}
connection = ConnectHandler(**device)
print("Connected.")
connection.disconnect()
print("Disconnected.")**Never run this with real credentials written in the file.** This example exists to show the shape of the call — the next section replaces the hardcoded username/password with a safe runtime prompt.
**device unpacks the dictionary into the keyword arguments ConnectHandler expects — the same dictionary-unpacking shape, just applied to a function call instead of a data structure.
The connection lifecycle
- Build connection parametersdevice_type, host, username, password
- ConnectHandler(**device)opens the SSH session
- Authenticatedevice checks the credentials
- Session openready to send commands
- disconnect()closes the session cleanly
Always close what you open
A connection left open holds a resource on the device — Cisco switches have a limited number of concurrent SSH sessions (VTY lines). A script that connects to fifty devices and never disconnects can genuinely lock other engineers out of a device. Calling disconnect() when you're done isn't optional cleanup — it's part of doing this correctly.
Supplying credentials safely
Never write a real username or password directly into a script. Two safe, standard ways to supply them at runtime instead:
import getpass
from netmiko import ConnectHandler
username = input("Username: ")
password = getpass.getpass("Password: ")
device = {
"device_type": "cisco_ios",
"host": "192.168.1.1", # placeholder
"username": username,
"password": password,
}
connection = ConnectHandler(**device)input() prompts for the username in plain text; getpass.getpass() prompts for the password without echoing it to the screen — the same behavior as a terminal login prompt. Nothing is ever written to a file.
import os
from netmiko import ConnectHandler
device = {
"device_type": "cisco_ios",
"host": "192.168.1.1", # placeholder
"username": os.environ["NETMIKO_USERNAME"],
"password": os.environ["NETMIKO_PASSWORD"],
}
connection = ConnectHandler(**device)os.environ reads values set outside the script — in the terminal session or a scheduler's configuration, never written into the code itself. This is the better fit for a script that runs unattended, on a schedule, without anyone at the keyboard to type a password.
What can go wrong when connecting
from netmiko import ConnectHandler, NetmikoTimeoutException, NetmikoAuthenticationException
try:
connection = ConnectHandler(**device)
except NetmikoTimeoutException:
print(f"{device['host']}: did not respond — check the IP and network path")
except NetmikoAuthenticationException:
print(f"{device['host']}: rejected the credentials")Two distinct exceptions for two distinct problems. A timeout means the device never answered at all — wrong IP, no route, or it's down. An authentication failure means it answered, but didn't accept the username or password.
What a real timeout actually looks like
Testing this against a guaranteed-unreachable address confirms Netmiko's real behavior: a connection attempt to an address with nothing listening raises NetmikoTimeoutException with a message that starts "TCP connection to device failed" and lists likely causes — wrong hostname/IP, wrong port, or a firewall in the way. That's exactly the category of problem a timeout signals: the network path itself, not the credentials.
Key takeaways
- ConnectHandler(**device) opens the SSH session; connection.disconnect() closes it — always close what you open.
- getpass() and input() prompt for credentials interactively; environment variables supply them for unattended, scheduled scripts — neither ever writes a credential into a file.
- NetmikoTimeoutException means the device never responded (a network-path problem); NetmikoAuthenticationException means it responded but rejected the credentials — different problems, different responses.
- This lesson's try/except around ConnectHandler is the beginning of the real connection/check function this module is building — the same shape as Phase 2.6's try/except around simulate_connection().