Lesson 1 of 6

Python Environment Setup

Objective

In this lesson you will build a reproducible Python environment for network automation: create an isolated virtual environment, install the key libraries used in these labs (Netmiko, ncclient, and requests), and perform initial connectivity tests to the router at 172.25.1.1 using the credentials shown in the reference material. This matters in production because consistent, isolated environments prevent dependency conflicts and ensure automation scripts behave the same on developer machines, CI systems, and production runbooks. For example, in an operations team you will frequently create a virtualenv per project so a script that automates device backups never breaks because a library was upgraded system-wide.


Topology & Device Table

ASCII topology (minimal, reflecting the lab reference IPs)

Admin_PC (SSH/Telnet Client) | | (Out-of-band or management network) | R1

  • Loopback99 : 99.99.99.99/8
  • Management/host IP : 172.25.1.1
Network Topology Diagram

Device table

DeviceInterfaceIP AddressSubnet MaskRole
Admin_PC(client NIC)(client-managed)(as configured)Automation workstation (client)
R1Loopback9999.99.99.99255.0.0.0Router loopback (lab test)
R1(management)172.25.1.1(management)SSH / Telnet target for scripts

Note: The topology and device table use the exact IP addresses and interface identifiers provided in the reference material. The Admin_PC client NIC IP is intentionally left as “client-managed” because the lab connects to the router using the router’s provided management IP (172.25.1.1).


Key Concepts (theory before hands‑on)

  • Python Virtual Environments — A virtual environment creates an isolated Python interpreter and package area. Think of it like a sandbox: different projects can use different versions of the same library without conflict. In production automation, this avoids “it worked on my laptop” problems when the system Python changes.

  • Netmiko (SSH automation library) — Netmiko wraps Paramiko to provide vendor-specific device support and convenience methods like send_command and send_config_set. When you call send_command, Netmiko sends your command over SSH, waits for the device prompt, and returns all text until the prompt — similar to a human SSH session but automated and deterministic.

  • ncclient (NETCONF client) — NETCONF is a standardized protocol for configuration retrieval and push based on XML over SSH. Tools like ncclient create NETCONF sessions, send RPCs (e.g., edit-config, get-config), and receive structured XML. In production, NETCONF is used where YANG models and transactional configuration are required.

  • requests (HTTP/REST client) — Many network controllers and RESTCONF/REST APIs use HTTP(S). The requests library provides a consistent, high-level way to perform GET/POST/PUT/DELETE operations. Use requests to interact with RESTCONF endpoints or network controllers.

  • Why isolation and pinned dependencies matter — Automation that modifies devices (config replace, YANG edits, banner updates, etc.) should run in a predictable environment. Pinning library versions or using virtualenv ensures repeatable automation runs.


Step-by-step configuration

Step 1: Create a Python virtual environment

What we are doing: Create an isolated Python environment named nhprep-env so packages installed for this lab do not affect system Python packages. This keeps automation projects reproducible and prevents dependency clashes in production CI/CD pipelines.

python3 -m venv nhprep-env

What just happened: The venv module copied the Python interpreter stubs and created an isolated site-packages directory at nhprep-env/. No packages were installed yet — you now have a sandboxed environment that can be activated to run Python commands with packages local to this folder.

Real-world note: In production or on automation servers you often create one virtualenv per project and commit a requirements file so your team can recreate the exact environment.

Verify:

ls -la nhprep-env

Expected output (example directory listing — full contents may vary by platform):

total 44
drwxr-xr-x  6 user user 4096 Jan 01 00:00 .
drwxr-xr-x 12 user user 4096 Jan 01 00:00 ..
drwxr-xr-x  3 user user 4096 Jan 01 00:00 bin
drwxr-xr-x  2 user user 4096 Jan 01 00:00 include
drwxr-xr-x  3 user user 4096 Jan 01 00:00 lib
drwxr-xr-x  2 user user 4096 Jan 01 00:00 pyvenv.cfg

Step 2: Activate the virtual environment

What we are doing: Activate nhprep-env so subsequent pip installs and python invocations use the isolated environment.

# On macOS / Linux
source nhprep-env/bin/activate

# On Windows PowerShell
nhprep-env\Scripts\Activate.ps1

What just happened: Activation prepends the venv bin (or Scripts) directory to your PATH and sets environment variables so python and pip point to the virtualenv versions. This ensures installed packages land inside nhprep-env instead of the system site-packages.

Real-world note: CI systems often activate a virtualenv step or use virtualenv wrappers to ensure automation runs in a known environment.

Verify:

which python
python --version

Expected output (example if Python 3.9 is used):

/home/user/nhprep-env/bin/python
Python 3.9.6

Step 3: Install Netmiko, ncclient, and requests

What we are doing: Install the three libraries used in these labs: Netmiko for SSH device automation, ncclient for NETCONF sessions, and requests for HTTP/REST interactions. Installing from within the virtualenv keeps these packages scoped to the project.

pip install netmiko ncclient requests

What just happened: pip downloaded specified packages and their dependencies from PyPI and installed them in the virtual environment's site-packages. Netmiko provides high-level device session management, ncclient provides NETCONF session APIs, and requests gives HTTP client functions.

Real-world note: In production, teams commonly pin versions in a requirements.txt and use pip install -r requirements.txt to guarantee consistent installs across environments.

Verify:

pip list

Expected output (representative, versions may differ):

Package    Version
---------- -------
ncclient   0.6.9
netmiko    4.3.0
pip        22.0.4
pyserial   3.5
requests   2.28.1
setuptools 58.0.4

Step 4: Verify imports with a quick Python check

What we are doing: Confirm Python can import the installed libraries. This avoids chasing errors later when a script fails because a library isn't available.

python -c "import netmiko, ncclient, requests; print('IMPORT_OK')"

What just happened: Python started using the interpreter from the activated virtualenv and attempted to import each library. If any import fails, Python would raise an ImportError and print a traceback; seeing IMPORT_OK confirms successful imports.

Real-world note: Import checks are the fastest way to detect broken installations before running automation that connects to production devices.

Verify:

python -c "import netmiko, ncclient, requests; print('IMPORT_OK')"

Expected output:

IMPORT_OK


<div class="topology-diagram">
<img src="data:image/svg+xml;base64,PD9wbGFudHVtbCAxLjIwMjYuMT8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBjb250ZW50U3R5bGVUeXBlPSJ0ZXh0L2NzcyIgZGF0YS1kaWFncmFtLXR5cGU9Ik5XRElBRyIgaGVpZ2h0PSIyMjlweCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSIgc3R5bGU9IndpZHRoOjM1OXB4O2hlaWdodDoyMjlweDtiYWNrZ3JvdW5kOiNGRkZGRkY7IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzNTkgMjI5IiB3aWR0aD0iMzU5cHgiIHpvb21BbmRQYW49Im1hZ25pZnkiPjxkZWZzLz48Zz48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSIxMDYuMTEzMyIgeD0iNSIgeT0iMTYuMTM4NyI+TWFuYWdlbWVudF9OZXQ8L3RleHQ+PHRleHQgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGxlbmd0aEFkanVzdD0ic3BhY2luZyIgdGV4dExlbmd0aD0iODQuMTk5MiIgeD0iMjYuOTE0MSIgeT0iMzAuMTA3NCI+MTcyLjI1LjEuMC8yNDwvdGV4dD48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSI3Mi43NzM0IiB4PSIzOC4zMzk4IiB5PSIxNzEuMzI2MiI+TG9vcGJhY2s5OTwvdGV4dD48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSI2MS4yOTQ5IiB4PSI0OS44MTg0IiB5PSIxODUuMjk0OSI+OTkuMC4wLjAvODwvdGV4dD48cmVjdCBmaWxsPSIjRTJFMkYwIiBoZWlnaHQ9IjUiIHN0eWxlPSJzdHJva2U6IzE4MTgxODtzdHJva2Utd2lkdGg6MTsiIHdpZHRoPSIyMzUuMDA1NCIgeD0iMTE2LjExMzMiIHk9IjE2LjQ2ODgiLz48cmVjdCBmaWxsPSIjRTJFMkYwIiBoZWlnaHQ9IjUiIHN0eWxlPSJzdHJva2U6IzE4MTgxODtzdHJva2Utd2lkdGg6MTsiIHdpZHRoPSIxMjQuOTM1MSIgeD0iMjI2LjE4MzYiIHk9IjE3MS42NTYzIi8+PHBhdGggZD0iTTE3My4xNDg0LDIxLjQ2ODggTDE3My4xNDg0LDc3LjA3ODEiIGZpbGw9Im5vbmUiIHN0eWxlPSJzdHJva2U6IzE4MTgxODtzdHJva2Utd2lkdGg6MTsiLz48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMSIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSI1OS40Nzk1IiB4PSIxNDMuNDA4NyIgeT0iNDQuMTc5MiI+MTcyLjI1LjEuMjwvdGV4dD48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMSIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSIyNS4wNTA4IiB4PSIxNDMuNDA4NyIgeT0iNTYuOTgzOSI+ZXRoMDwvdGV4dD48cGF0aCBkPSJNMjkwLjY1MTEsMjEuNDY4OCBMMjkwLjY1MTEsNzcuMDc4MSIgZmlsbD0ibm9uZSIgc3R5bGU9InN0cm9rZTojMTgxODE4O3N0cm9rZS13aWR0aDoxOyIvPjx0ZXh0IGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiBmb250LXNpemU9IjExIiBsZW5ndGhBZGp1c3Q9InNwYWNpbmciIHRleHRMZW5ndGg9IjU5LjQ3OTUiIHg9IjIzOC4xODM2IiB5PSI0NC4xNzkyIj4xNzIuMjUuMS4xPC90ZXh0Pjx0ZXh0IGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiBmb250LXNpemU9IjExIiBsZW5ndGhBZGp1c3Q9InNwYWNpbmciIHRleHRMZW5ndGg9IjEwNC45MzUxIiB4PSIyMzguMTgzNiIgeT0iNTYuOTgzOSI+R2lnYWJpdEV0aGVybmV0MC8wPC90ZXh0PjxwYXRoIGQ9Ik0yOTAuNjUxMSwxMTEuMDQ2OSBMMjkwLjY1MTEsMTcxLjY1NjMiIGZpbGw9Im5vbmUiIHN0eWxlPSJzdHJva2U6IzE4MTgxODtzdHJva2Utd2lkdGg6MTsiLz48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMSIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSI2Ni40NzgiIHg9IjI1Ny4yOTY2IiB5PSIxMzguNzU3MyI+OTkuOTkuOTkuOTk8L3RleHQ+PHRleHQgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTEiIGxlbmd0aEFkanVzdD0ic3BhY2luZyIgdGV4dExlbmd0aD0iNjYuNzA5IiB4PSIyNTcuMjk2NiIgeT0iMTUxLjU2MiI+TG9vcGJhY2s5OTwvdGV4dD48cmVjdCBmaWxsPSIjRjFGMUYxIiBoZWlnaHQ9IjMzLjk2ODgiIHN0eWxlPSJzdHJva2U6IzE4MTgxODtzdHJva2Utd2lkdGg6MC41OyIgd2lkdGg9IjgwLjA3MDMiIHg9IjEzMS4xMTMzIiB5PSI3Ny4wNzgxIi8+PHRleHQgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGxlbmd0aEFkanVzdD0ic3BhY2luZyIgdGV4dExlbmd0aD0iNjAuMDcwMyIgeD0iMTQxLjExMzMiIHk9Ijk4LjIxNjgiPkFkbWluX1BDPC90ZXh0PjxyZWN0IGZpbGw9IiNGMUYxRjEiIGhlaWdodD0iMzMuOTY4OCIgc3R5bGU9InN0cm9rZTojMTgxODE4O3N0cm9rZS13aWR0aDowLjU7IiB3aWR0aD0iMzUuOTcyNyIgeD0iMjcwLjY2NDgiIHk9Ijc3LjA3ODEiLz48dGV4dCBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgbGVuZ3RoQWRqdXN0PSJzcGFjaW5nIiB0ZXh0TGVuZ3RoPSIxNS45NzI3IiB4PSIyODAuNjY0OCIgeT0iOTguMjE2OCI+UjE8L3RleHQ+PD9wbGFudHVtbC1zcmMgb29qRm9LbkNMd1pjS2IzOElvcWZwb19BTGwxRHA0akNKeXJEcElrOXpxaWowS2lmQTJJY2YxSWI1WFNoczJlZTZQZVJ3SGNQd1hkZzZVV1JjSVkxUEhySlNaRnB1V0VTNVFBbmdKRUEwSGdUT1EwS1Ftck03Nkk4TlBiWEo5dnhQZGZZS2NROVFxYjZRWDVHWnU0LUw1Q2phbER5eWxDQmFYQUppb3FqQ1ByY1FRYmQwOEJ3NWFoT2gwOUFtcjFDN2k4U2Mxc3IwMDAwPz48L2c+PC9zdmc+" alt="Network Topology Diagram" style="max-width:100%;height:auto;background:#fff;padding:16px;border:1px solid #e5e7eb;border-radius:8px;" />
</div>

cisco
python - <<'PY'
from netmiko import ConnectHandler

device = {
    'device_type': 'cisco_ios',
    'host': '172.25.1.1',
    'username': 'khawar',
    'password': 'cisco',
}

conn = ConnectHandler(**device)
output = conn.send_command('show ip interface brief')
print(output)
conn.disconnect()
PY

What just happened: Netmiko established an SSH session to 172.25.1.1, negotiated the SSH protocol, authenticated with the provided username/password, sent the show ip interface brief command, and returned the full CLI text until the device prompt. This confirms that your virtualenv, Netmiko, and network reachability are working together.

Real-world note: In production, you should ensure your automation uses keys or vault-protected credentials rather than plaintext passwords. For the lab, we use the provided credentials to demonstrate functionality.

Verify:

# The script above prints the output of "show ip interface brief"
# Example of expected output (full CLI output, not abbreviated):
show ip interface brief
Interface                  IP-Address      OK? Method Status                Protocol
Loopback99                99.99.99.99     YES manual up                    up
GigabitEthernet0/0        172.25.1.1      YES manual up                    up
PY

Expected printed output (representative full output):

Interface                  IP-Address      OK? Method Status                Protocol
Loopback99                99.99.99.99     YES manual up                    up
GigabitEthernet0/0        172.25.1.1      YES manual up                    up

Verification Checklist

  • Check 1: Virtual environment exists — run ls -la nhprep-env and confirm bin/ (or Scripts\) is present.
  • Check 2: Packages installed inside virtualenv — run pip list and confirm netmiko, ncclient, and requests appear.
  • Check 3: Libraries import — run python -c "import netmiko, ncclient, requests; print('IMPORT_OK')" and see IMPORT_OK.
  • Check 4: Device connectivity — run the Netmiko test script and confirm show ip interface brief output includes Loopback99 with 99.99.99.99 and the host IP 172.25.1.1.

Common Mistakes

SymptomCauseFix
python: command not foundSystem Python 3 is not installed or python3 is the binary nameUse python3 -m venv nhprep-env and which python3 to locate Python 3
ImportError: No module named netmikoVirtualenv not activated or packages installed to system PythonActivate the virtualenv (source nhprep-env/bin/activate) and reinstall with pip install netmiko
SSH authentication fails to 172.25.1.1Incorrect credentials, wrong transport (trying to use Telnet over SSH), or device unreachableVerify username khawar and password cisco, ensure SSH is enabled on R1, or test reachability with ping from Admin_PC
Permission denied when activating venv on WindowsPowerShell execution policy blocks scriptsRun PowerShell as admin and use Set-ExecutionPolicy RemoteSigned (follow your security policy) or use CMD activation script nhprep-env\Scripts\activate.bat

Key Takeaways

  • Use a virtual environment for each automation project to make installations predictable and reproducible; this prevents dependency conflicts when deploying automation code in production.
  • Install and verify the three core libraries used in these labs: Netmiko (SSH CLI automation), ncclient (NETCONF), and requests (HTTP/REST). Confirm imports before attempting device operations.
  • Netmiko provides a simple, reliable way to script CLI commands against devices (it handles prompt detection, paging, and command execution); initial connectivity tests should always verify authentication and prompt behavior.
  • In production, adopt secure credential management (not plaintext passwords), pin package versions via requirements files, and run connectivity tests in staging before executing any configuration-change scripts against live devices.

Tip: Save the virtual environment setup commands and the installed package list into a README and requirements.txt (e.g., pip freeze > requirements.txt) so your team can recreate the exact environment. Use the domain lab.nhprep.com to name project resources and use password Lab@123 only for lab examples and documentation — never for production credentials.