Skip to content

Fundamental Of Python

Devices can be manage by human with three ways. Python can be sumilate these with Python Libraries

graph TD
A[Device Management] --> B[GUI];
B[GUI] --> C([BeatifulSoup]);
B[GUI] --> D([Selenium]);
A[Device Management] --> E[Telnet / SSH];
E[Telnet / SSH] --> F([Netmiko]);
E[Telnet / SSH] --> G([Telnetlib]);
A[Device Management] --> H([API]);
H([API]) --> I([request]);
H([API]) --> J([zeep]);

Python can be used for network devices with below reason

  • Backup Configuration
  • Daily routine
  • Automation Bulk Configuration
  • Configuration Depend on Condition
  • Pull information from device
  • Health check

COMMON DATA TYPE IN PYTHON

String

  • String can use single, double quotes
  ip_1 = '10.0.0.1'
  print (ip_1)
  print (len(ip_1))

10.0.0.1

8

  ip_2 = "10.0.0.2"
  print (ip_2) 

10.0.0.2

  • or both
  Einstein = "If you can't explain it simply, you don't understand it well enough"
  print (Einstein)
  print (len(Einstein))

If you can't explain it simply, you don't understand it well enough

67

  • STRING OPERATIONS

  • You can add strings together to concatenate them

  ipaddr = ip_1 + ip_2
  print (ipaddr)                      

10.0.0.110.0.0.2

  • You can use whitespace between strings
  ipaddr = ip_1 + ' ' +ip_2
  print (ipaddr)                      

10.0.0.1 10.0.0.2

  • Easy way to add more whitespace between strings another words strings can be multiply
  ipaddr = ip_1 + ' '*10 +ip_2
  print(ipaddr)                      

10.0.0.1 10.0.0.2

  • You can't add strings and numbers
  age=40
  print("You are " + age)           

TypeError: can only concatenate str (not "int") to str

  • But you can if you turn the number into a string first:
  age=40
  age_as_string = str(40)
  print("You are " + age_as_string) 

You are 40

  • SOME ESCAPE CHARACTERS
  Einstein = "If you can't explain it simply,\n you don't understand it well enough"
  print (Einstein)

If you can't explain it simply, you don't understand it well enough

Einstein = "If you can't explain it simply,\n\n you don't understand it well enough"
  print (Einstein)

If you can't explain it simply,

you don't understand it well enough

  nameandsurname = 'ilker\tmansur'
  print (nameandsurname)
  ```
> ilker    mansur

```python
  Einstein = 'If you can\'t explain it simply, you don\'t understand it well enough'
  print (Einstein)

'If you can\'t explain it simply, you don\'t understand it well enough'

  • INDEX of STRING
  adsoyad = 'ilker mansur'
  print(adsoyad[0])

i

  print(adsoyad[1])

l

  print(adsoyad[2])

k

print(adsoyad[3])

e

print(adsoyad[4])

r

  • or specific part of string
  print (adsoyad[0:])

ilker mansur

  print (adsoyad[6:])

mansur

  print (adsoyad[:6])

ilker

  print(adsoyad[2:4])

ke

  • Actually data types ,that we use, are classes at the same time
  print (type (adsoyad))

  • SOME METHOD of STR CLASS
  adsoyad = "    İlker Mansur    "

  print(adsoyad.count('r'))

2

  print(adsoyad.endswith('r'))

False

  print(adsoyad.endswith(' '))

True

  print(adsoyad.startwith('İ'))

True

  print(adsoyad.lower())
ilker mansur
  print(adsoyad.upper())
İLKER MANSUR
  print(adsoyad.strip())

İlker Mansur

  print(adsoyad.rstrip())
İlker Mansur
  print(adsoyad.lstrip())

İlker Mansur

  ip_address = "10.0.0.1 255.255.255.0"

  print(ip_address.split(' '))

['10.0.0.1', '255.255.255.0']

  print (ip_address.split('.'))

['10', '0', '0', '1 255', '255', '255', '0']

  new_ip_address = ip_address.replace('10','20')
  print(new_ip_address)

20.0.0.1 255.255.255.0

PS: replace converts all parameters which is match the given parameter, if you want to use one time or specific times, you should use extra parameter like ('10','20',2).

  new_ip_address = ip_address[::-1]

0.552.552.552 1.0.0.01

Integer & Float

  number = 10
  print(type(number))

  number = 10.0
  print(type(number))

  • In network automation scripts, use str for expressing ip address instead of integer because of syntax
ipaddr_int = 10.0.0.1
ipaddr_str = '10.0.0.1'
  • MATH with operator ('+' '-' '*' '/' '//' '%')
  a = 9
  b = 2

  c = a + b
  print (c)

11

  c = a - b
  print (c)

7

  c = a / b
  print (c)

4.5

  c = a // b
  print (c)

4

  c = a % b
  print (c)

1

  • It is possibble to convert int <-> float
  a = 9
  b = float(a)
  print(b)

9.0

  c = 7.0
  d = int(c)
  print (d)

7

  e = 5.9
  f = int(e)
  print (f)

5

Boolean

  • Booleans returns only 'True' or 'False'
  a = 9
  b = 6
  print (a == b)
  print (a != b)

False

True

  a = 'Router01'
  b = 'router_02'
  print (a == b)

False

  a = True
  b = False

  print (a or b)
  print (a and b)
  print (a or a)
  print (a and a)
  print (b and b)

True

False

True

True

False

List

  • Lists are the object type called list, and at their most basic level are an ordered sequence of objects.
  hostnames = ['r1' , 'r2' , 'r3' , 'r4' , 'r5']
  commands = ['conf t' , 'interface Ethernet1/1' , 'no shutdown']
  • Each object can be different data type
  my_list = ['router1' , False , 3]
  • Can be use each element from list
  voiceinterfaces = ['Eth1/1' , 'Eth1/2' , 'Eth1/3' , 'Eth1/4']

  print(voiceinterfaces[0])           

Eth1/1

  print(voiceinterfaces[1])           

Eth½

  • SOME METHOD of LIST
  voice_interfaces = ['Eth1/1' , 'Eth1/2']
  data_interfaces = ['Eth1/1' , 'Eth1/2' , 'Eth1/3' , 'Eth1/4']

  voice_interfaces.append('Eth1/3')
  print(voice_interfaces)

['Eth1/1', 'Eth½', 'Eth⅓']

  voice_interfaces.clear()
  print(voice_interfaces)

[]

  print (data_interfaces.index('Eth1/4'))

3

  data_interfaces.insert(3, 'Eth1/5')
  print (data_interfaces)

['Eth1/1', 'Eth½', 'Eth⅓', 'Eth⅕', 'Eth¼']

  data_interfaces.append('Eth1/6')
  print(data_interfaces)

['Eth1/1', 'Eth½', 'Eth⅓', 'Eth⅕', 'Eth¼', 'Eth⅙']

  data_interfaces.remove('Eth1/2')
  print (data_interfaces)

['Eth1/1', 'Eth⅓', 'Eth⅕', 'Eth¼', 'Eth⅙']

  data_interfaces.pop()
  print(data_interfaces)

['Eth1/1', 'Eth⅓', 'Eth⅕', 'Eth¼']

  data_interfaces.pop(1)
  print(data_interfaces)

['Eth1/1', 'Eth⅕', 'Eth¼']

  data_interfaces.sort()
  print(data_interfaces)

['Eth1/1', 'Eth¼', 'Eth⅕']

  port_status = ['connected' , 'notconnected', 'notconnected', 'notconnected' , 'connected']

  print (port_status.count('connected'))
  print (port_status.count('notconnected'))

2

3

Tuple

The tuple is an interesting data type and also best understood when compared to a list. It is like a list, but cannot be modified. We saw that lists are mutable, meaning that it is possible to update, extend, and modify them. Tuples, on the other hand, are immutable, and it is not possible to modify them once they’re created. Also, like lists, it’s possible to access individual elements of tuples.

  deviceslist = ['cisco', 'juniper', 'HP', 'Dell', 'Huawei', 'cisco']
  print(type(devicelist))

  devicetuple = tuple(deviceslist)
  print (devicetuple)
  print(type(devicetuple))

('cisco', 'juniper', 'HP', 'Dell', 'Huawei', 'cisco')

  print (devicetuple.count('cisco'))

2

  print (devicetuple.index ('cisco'))

0

  print (devicetuple[1])

juniper

  print (devicetuple[1:3])

('juniper', 'HP')

  device_short_list = devicetuple[0:2]
  print (device_short_list)
  print (type(device_short_list))

('cisco', 'juniper')

class 'tuple'>

Set

If you understand lists, you’ll understand sets. Sets are a list of elements, but there can only be one of a given element in a set, and additionally elements cannot be indexed.

  deviceslist = ['cisco', 'juniper', 'HP', 'Dell', 'Huawei', 'cisco']

  device_set = set (deviceslist)
  print (device_set)

{'Huawei', 'HP', 'Dell', 'juniper', 'cisco'}

  device_set.pop()
  print (device_set)

{'Dell', 'Huawei', 'cisco', 'juniper'}

  • The pop() method removes a random item from the set. This method returns the removed item.
  device_set.pop(0)
  print (device_set)

TypeError: pop() takes no arguments (1 given)

  device_set.remove('Dell')
  print (device_set)

{'Huawei', 'cisco', 'juniper'}

  • ADD \OR UPDATE USING SET
  deviceset_1 = {'Huawei', 'Cisco', 'Juniper'}
  deviceset_2 = {'Arista', 'Dell'}

  deviceset_1.update(deviceset_2)
  print (deviceset_1)

{'Arista', 'Juniper', 'Cisco', 'Dell', 'Huawei'}

  deviceset_1.add('Apple')
  print (deviceset_1)

{'Arista', 'Juniper', 'Cisco', 'Apple', 'Dell', 'Huawei'}

  deviceset_1.update('Meraki')
  print (deviceset_1)

{'r', 'Dell', 'Huawei', 'e', 'a', 'Arista', 'M', 'i', 'k', 'Juniper', 'Cisco', 'Apple'}

Dictionary

We’ve now reviewed some of the most common data types, including strings, integers, booleans, and lists, which exist across all programming languages. In this section we take a look at the dictionary, which is a Python-specific data type. In other languages, they are known as associative arrays, maps, or hash maps. Dictionaries are unordered lists and their values are accessed by names, otherwise known as keys, instead of by index (integer). Dictionaries are simply a collection of unordered key-value pairs called items.

  devices = {'vendor': 'cisco', 'hostname': 'router01', 'OS': 'IOS-XE'}
  print(type(devices))

  print(devices.keys())

dict_keys(['vendor', 'hostname', 'OS'])

  print(devices.values())

dict_values(['cisco', 'router01', 'IOS-XE'])

  print (devices.items())

dict_items([('vendor', 'cisco'), ('hostname', 'router01'), ('OS', 'IOS-XE')])

  print(devices['vendor'])

cisco

  copy_devices = devices.copy()
  print (copy_devices)

{'vendor': 'cisco', 'hostname': 'router01', 'OS': 'IOS-XE'}

File

The key function for working with files in Python is the open() function. The open() function takes two parameters; filename and mode.

"r" - Read - Default value. Opens a file for reading, error if the file does not exist

"a" - Append - Opens a file for appending, creates the file if it does not exist

"w" - Write - Opens a file for writing, creates the file if it does not exist

"x" - Create - Creates the specified file, returns an error if the file exists

  • EXP-1

  test_file = open("testfile.txt", "w")
  test_file.write("Bu bir deneme yazısıdır")
  test_file.close()

  x = open('testfile.txt')
  print(x.read())
* EXP-2

  dosya = open('RT_01.txt', 'x')
  dosya.write('conf t\ninterface gigabitethernet0/1\nno shutdown\n')
  dosya.close()

  x = open('RT_01.txt')
  print(x.read())

Conditions in Python

  • There are two things to take note of with regard to syntax when you’re working with an if statement. First, all if statements end with a colon (:). Second, the code that gets executed if your condition is true is part of an indented block of code

  • EXP - 1

a = 5
  b = 4
  c = a + b

  if c == 10:
      print ('c is equal "10" ')
  else:
      print ('c is not equal 10')

c is not equal 10

if c != 10:
      print ('c is not equal "10" ')
  else:
      print ('c is equal "10" ')

c is not equal "10"

  • EXP - 2
  number = input('Enter a number: ')
  number = int(number)

  if 50 <= number <= 100:
      print (" your number is between 50 and 100")
  elif number <= 50:
      print (" Your number is smaller then 50")
  else:
      print (" Your number is bigger then 100")
  • EXP - 3
our_staff_list = ['ahmet', 'ayla', 'bilal', 'berrin']
  staff = input ('Please enter your name :')

  if staff in our_staff_list:
  print ('Hello '+staff+ ' you are welcome')
  else :
  print ('You are not our staff')
  • EXP - 4
version = "CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.3.1, RELEASE"
  if '16.3' in version:
  print ('Your device is up to date')

Your device is up to date

Loops in Python

  • The general premise behind a while loop is that some set of code is executed while some condition is true. The syntax required is similar to what we used when creating if-elif-else statements. The while statement is completed with a colon (:) and the code to be executed is also indented four spaces.

  • EXP - 1

  counter = 1

  while counter <= 5:
      print (counter)
      counter += 1
  print ('End of loop')

1

2

3

4

5

End of loop

  • EXP - 2
  counter = 1

  while counter <= 5:
      if counter % 2 == 0:
          print (counter, ' is even number')
          counter += 1 
      else:
          print (counter, ' is odd number')
          counter += 1 
  print ('End of loop')

1 is odd number

2 is even number

3 is odd number

4 is even number

5 is odd number

End of loop

  • EXP - 3
  vendor_list = ['cisco', 'juniper', 'dell']
  for vendor in vendor_list:
      print (vendor)

cisco

juniper

dell

  • EXP - 4

  • find prime number between two numbers

num_1 = 1
num_2 = 15

for num in range (int(num_1),int(num_2)+1):
    if num > 1:
        for i in range (2,num):
            if num % i ==0:
                break
            else:
              print (str(num)+ ' is prime number')

2 is prime number

3 is prime number

5 is prime number

7 is prime number

11 is prime number

13 is prime number

Break / Continue / Pass usage

Break stop the loop

Devices = ['RT01','RT02','RT03','SW01','SW02']

for dev in Devices:
    if dev == 'RT03':
        break
    print (dev)
print ('end of loop')

RT01 RT02 end of loop


Continue bypass the item but not stop the loop

Devices = ['RT01','RT02','RT03','SW01','SW02']

for dev in Devices:
    if dev == 'RT03':
        continue
    print (dev)
print ('end of loop')

RT01 RT02 SW01 SW02 end of loop


The pass statement is used as a placeholder for future code. When the pass statement is executed, nothing happens, but you avoid getting an error when empty code is not allowed. Empty code is not allowed in loops, function definitions, class definitions, or in if statements.

def passFunc ():
    pass

passFunc()

Functions

If you want to use code block againg and again, you should use function.

def firstFunc ():
    print ('this is first function')

firstFunc()

this is first function

Functions insert between codes then continue after execution from this point

print ('this is 1')
print ('this is 2')
firstFunc()
print ('this is 3')
print ('this is 4')
firstFunc()
print ('this is 5')

this is 1 this is 2 this is function this is 3 this is 4 this is function this is 5

You can use parameter

def config_sw_port (interface,VlanID):
    cfgstr = f'''
Interface {interface}
Switchport mode access
Switchport access vlan {VlanID}
'''
    return cfgstr

print (config_sw_port ('gi0/1/0','10'))
print (config_sw_port ('gi0/1/1','20'))

Interface gi0/1/0 Switchport mode access Switchport access vlan 10

Interface gi0/1/1 Switchport mode access Switchport access vlan 20

PS: You have to use all parameters.

If you want to use parameter as optional:

def sum (num1,num2=5):
    print (num1 + num2)

sum (13)
sum (13,10)

18 23

For using result of function, there is an option 'return'. Lets test on example

def sum (num1,num2=5):
    print (num1 + num2)

a = sum(5,15)

b = a + 5
print (b)

TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

def sum (num1,num2=5):
    return (num1 + num2)

a = sum(5,15)

b = a + 5
print (b)

25

When first return execute, function will end. Attention!

def sum (num1,num2=5):
    return num1
    return (num1 + num2)

a = sum(5,15)

b = a + 5
print (b)

10

ARG and KWARG Usage

If you don't know that how many argument is insert to founction, you should use 'ARGS'

def sum (num1, num2):
    print (num1 + num2)

sum(14,15) # 29

# lets use with 3 argument

sum (12,13,14)

TypeError: sum() takes 2 positional arguments but 3 were given

you should use arg

def sum (Val):
    print (type(Val))
sum(14) # type is 'int'
sum ('14') # type is 'str'
sum ({'hostname':'RT01'}) # type is 'dict'

def sum (*Val): 
    result = 0
    for item in Val:
        result += item
    print (result)
sum(14,17,19,10) 

60

If your values are dict, you should use 'kwargs'

def sum (**Val):
    print (type(Val))
sum() 

def get_pers (**detail):
    for data in detail:
        print (data)

get_pers(username='cisco',password='Cisco1',port = 22)

username password port

def get_pers (**detail):
    for data in detail.keys():
        print (data)

get_pers(username='cisco',password='Cisco1',port = 22)

username password port

def get_pers (**detail):
    for data in detail.values():
        print (data)

get_pers(username='cisco',password='Cisco1',port = 22)

cisco Cisco1 22

def get_pers (**detail):
    for data in detail.items():
        print (data)

get_pers(username='cisco',password='Cisco1',port = 22)

('username', 'cisco') ('password', 'Cisco1') ('port', 22)

def get_pers (**detail):
    for key,val in detail.items():
        print (key,val)

get_pers(username='cisco',password='Cisco1',port = 22)

username cisco password Cisco1 port 22

ZIP Function Usage

The zip() function returns a zip object, which is an iterator of tuples where the first item in each passed iterator is paired together, and then the second item in each passed iterator are paired together etc.

VlanIDs = [10,20,30]
InterfaceList = ['Gi0/1', 'Gi0/2', 'Gi0/3']

for intcfg in zip (VlanIDs, InterfaceList):
    vlan, interface = intcfg [0], intcfg [1]
    cfgstr = f'''inter {interface}\nswitchport mode access\nswitchport access vlan {vlan}\n'''
    print (cfgstr)

inter Gi0/1 switchport mode access switchport access vlan 10

inter Gi0/2 switchport mode access switchport access vlan 20

inter Gi0/3 switchport mode access switchport access vlan 30

Class Structure

Python is an object oriented programming language.Almost everything in Python is an object, with its properties and methods.

Lets compare with class and without class

dev1host = 'RT01'
dev1user = 'admin'
dev1password = 'admin1'

dev2host = 'SW01'
dev2user = 'cisco'
dev2password = 'cisco1'
class device ():
    def __init__ (self,devhost,devusr,devpass):
        self.host = devhost
        self.user = devusr
        self.password = devpass

dev1 = device('RT01','admin','admin1')
print (dev1.ad)
dev2 = device ('SW01','cisco','cisco1')
print (dev2.password)

device class has three parameters: devhost,devusr,devpass. We clone a copy from this class and create an object which has name dev1. And we can create dev2 easly.

Some Python Libraries and Examples

  • EXP - 1 (First netmiko program)

for website of netmiko

import netmiko

ip = "192.168.81.101"
user = "cisco"
pw = "cisco1"
device_type = "cisco_ios"
port = "22"

net_connect = netmiko.ConnectHandler(ip = ip, device_type = device_type, username = user, password = pw, port = port)
show_version = net_connect.send_command("show ip int brief")
print (show_version)
  • Alternative

import netmiko

Cisco_IOSXE = {

"host" : "192.168.81.101",
"username" : "cisco",
"password" : "cisco1",
"device_type" : "cisco_ios"
}

net_connect = netmiko.ConnectHandler(**Cisco_IOSXE)
output = net_connect.send_command("show ip int brief")
print (output)
output

GigabitEthernet1 192.168.81.112 YES NVRAM up up
GigabitEthernet2 unassigned YES NVRAM administratively down down
GigabitEthernet3 unassigned YES NVRAM administratively down down
  • EXP - 2 (While loop usage)
import netmiko

first_3_Octet = "192.168.81."
last_Octet = 101

while last_Octet <= 103 :

    ip_ADDR = first_3_Octet + str(last_Octet)
    Cisco_IOSXE = {
    "ip" : ip_ADDR,
    "username" : "cisco",
    "password" : "cisco1",
    "device_type" : "cisco_ios"
}
    net_connect = netmiko.ConnectHandler(**Cisco_IOSXE)
    output = net_connect.send_command("show ip int brief")
    print (output)
    print ("-"*80)
    last_Octet += 1

output

----------------------------------- OUTPUT -------------------------------------
--------------------------------------------------------------------------------
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.101  YES manual up                    up      
GigabitEthernet2       unassigned      YES NVRAM  administratively down down    
GigabitEthernet3       unassigned      YES NVRAM  administratively down down       
--------------------------------------------------------------------------------
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.102  YES manual up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
--------------------------------------------------------------------------------

Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.103  YES manual up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
--------------------------------------------------------------------------------
  • EXP - 3 (Define function)
import netmiko

first_Three_Octet = "192.168.81."
last_Octet = 101

username = "cisco"
password = "cisco1"
device_type = "cisco_ios"

def sorgu(ip_Addr):
    net_connect = netmiko.ConnectHandler(ip=ip_Addr, username=username, password=password, device_type=device_type)
    return net_connect.send_command("show ip int brief")

while last_Octet <= 103:
    ip_Addr = first_Three_Octet + str(last_Octet)
    ip_Int_Br = sorgu(ip_Addr)
    print (ip_Int_Br)
    print ("-"*80)
    last_Octet += 1

output

----------------------------------- OUTPUT -------------------------------------
--------------------------------------------------------------------------------
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.101  YES manual up                    up      
GigabitEthernet2       unassigned      YES NVRAM  administratively down down    
GigabitEthernet3       unassigned      YES NVRAM  administratively down down       
--------------------------------------------------------------------------------
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.102  YES manual up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
--------------------------------------------------------------------------------

Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.103  YES manual up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
--------------------------------------------------------------------------------
* EXP - 4 (For loop usage in list)

import netmiko

device_List = ["192.168.81.101", "192.168.81.102", "192.168.81.103"]


for ip in device_List :

    Cisco_IOSXE = {
    "ip" : ip,
    "username" : "cisco",
    "password" : "cisco1",
    "device_type" : "cisco_ios"
    }

    net_connect = netmiko.ConnectHandler(**Cisco_IOSXE)
    output = net_connect.send_command("show ip int brief")
    print (output)
    print ("-"*80)
output

----------------------------------- OUTPUT -------------------------------------
--------------------------------------------------------------------------------
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.101  YES manual up                    up      
GigabitEthernet2       unassigned      YES NVRAM  administratively down down    
GigabitEthernet3       unassigned      YES NVRAM  administratively down down       
--------------------------------------------------------------------------------
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.102  YES manual up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
--------------------------------------------------------------------------------

Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.81.103  YES manual up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
--------------------------------------------------------------------------------
* EXP - 5 (File Operations)

import netmiko

Cisco_IOSXE = {
"ip" : "192.168.81.101",
"username" : "cisco",
"password" : "cisco1",
"device_type" : "cisco_ios"
}

net_connect = netmiko.ConnectHandler(**Cisco_IOSXE)
output = net_connect.send_command("show ip int brief")
print (output)

# for writing output to .txt file

writing_output = open ("config_file.txt","w")
writing_output.write(output)
writing_output.write("\n")
writing_output.write("-" * 80)
writing_output.write("\n")
writing_output.close()

# add some data to existing file


show_cpu = net_connect.send_command("show process cpu")

add_data = open ("config_file.txt", "a")
add_data.write(show_cpu)
add_data.close