https://www.arista.com/assets/data/pdf/Whitepapers/Arista_EOS_parser.pdf
Arista EOS CLI is implemented in Python, so you can customize the CLI yourself. Of course it is limited to simple output instead of complicated contents.
Step 1: Modify the CLI script
bn303.17:40:17#bash
Arista Networks EOS shell
[admin@bn303 ~]$ cd /usr/lib/python2.7/site-packages/CliPlugin/
[admin@bn303 CliPlugin]$ vi RoutingBgpShowCli.py
[admin@bn303 CliPlugin]$ sudo vi RoutingBgpCli.py
Step 2: save the new CLI script and load up during boot
copy the modified to /mnt/flash
the /usr/lib is file system in memory, unsustainable after reboot.
vi /mnt/flash/rc.eos, so copy the save script to the location
Disclaimer: The information contained in this blog is for informational purposes only and should not be considered as official documentation on any subject matter. The postings on this blog are my own and do not necessarily represent the opinions of my current and previous employers.
Showing posts with label python. Show all posts
Showing posts with label python. Show all posts
12/02/2018
11/29/2018
Python Notes (3) - Beautiful Python Code by Raymond Hettinger
https://www.youtube.com/watch?v=OSGv2VnC0go
Faster and prettier code:
1. Looping backwards
for color in reversed(colors):
print color
2. Looping over collection and indices
for i, color in enumerate(colors):
print i, ":", color
3. Zip of 2 lists
for name, color in zip(names, colors):
print name, ":", color
! zip has higher memory req, prone to cache miss;
! in python 3.x, using izip instead of zip
4. Sorted list
for color in sorted(colors):
for color in sorted(colors, reverse=True):
def compare_length(c1, c2):
if len(c1) < len(c2): return -1
if len(c1) > len(c2): return 1
return 0
for color in sorted(colors, cmp=compare_length):
for color in sorted(colors, key=len):
Looping over a dict with keys and values:
for k,v in d.items(): # req. memory to store list
for k,v in d.iteritems(): # use iterator instead of mem
Counting with dict
d ={}
for color in colors:
d[color] = d.get(color, 0) + 1
d = defaultdict(int)
for color in colors:
d[color] += 1
Grouping with dictionaries:
# group the list by length
names = ['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty']
#old
d = {}
for name in names:
key = len(name)
if key not in d:
d[key] = []
d[key].append(name)
#1
d = {}
for name in names:
key = len(name)
d.setdefault(key, []).append(name)
#2
d = defaultdict(list)
for name in names:
key = len(name)
d[key].append(name)
Function calls with keyword arguments
twitter_search('@obama', False, 20, True)
twitter_search('@obama', retweets=False, numtweets=20,
popular=True)
Faster and prettier code:
1. Looping backwards
for color in reversed(colors):
print color
2. Looping over collection and indices
for i, color in enumerate(colors):
print i, ":", color
3. Zip of 2 lists
for name, color in zip(names, colors):
print name, ":", color
! zip has higher memory req, prone to cache miss;
! in python 3.x, using izip instead of zip
4. Sorted list
for color in sorted(colors):
for color in sorted(colors, reverse=True):
def compare_length(c1, c2):
if len(c1) < len(c2): return -1
if len(c1) > len(c2): return 1
return 0
for color in sorted(colors, cmp=compare_length):
for color in sorted(colors, key=len):
Looping over a dict with keys and values:
for k,v in d.items(): # req. memory to store list
for k,v in d.iteritems(): # use iterator instead of mem
Counting with dict
d ={}
for color in colors:
d[color] = d.get(color, 0) + 1
d = defaultdict(int)
for color in colors:
d[color] += 1
# group the list by length
names = ['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty']
#old
d = {}
for name in names:
key = len(name)
if key not in d:
d[key] = []
d[key].append(name)
#1
d = {}
for name in names:
key = len(name)
d.setdefault(key, []).append(name)
#2
d = defaultdict(list)
for name in names:
key = len(name)
d[key].append(name)
Function calls with keyword arguments
twitter_search('@obama', False, 20, True)
twitter_search('@obama', retweets=False, numtweets=20,
popular=True)
Packing/Unpacking = simultaneous state updates
x, y, dx, dy = ( x + dx *t,
y + dy *t,
influence(m,x,y),
influence(m,x,y))
Concatenating strings
', '.join(names)
Updating sequences
names = ['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty']
del names[0]
names.pop(0)
names.insert(0, 'mark')
#==>
names = deque(['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty'])
del names[0]
names.popleft()
names.appendleft('mark')
Python Notes (2)
1. Sort:
>>> p.sort(key=lambda x:(x[0], x[2]))
>>> p
[[1, 7, 2], [1, 2, 3], [1, 2, 5], [1, 3, 7], [2, 4, 6], [3, 1, 0], [3, 2, 1]]
>>> p.sort(key=lambda x:(-x[0], x[2]))
>>> p
[[13, 1, 0], [3, 2, 1], [2, 4, 6], [1, 2, 3], [1, 2, 5], [1, 3, 7], [-1, 7, 2]]
1) No duplicate
2) No order
3) Sets contain only hashable items, for __contain__ method
4) Sets have operator like "-"
_set = set([1,2,3,3]) # (1,2,3)
l1 = [1,2,3,4]
- sorted() vs list.sort()
- Sorted() returns a new list vs list.sort() does in place.
- list.sort() only for list. But sorted() for all iterables.
- key function and (reverse=True)
- Sorted by multiple elements, like by first item then 2nd.
>>> p.sort(key=lambda x:(x[0], x[2]))
>>> p
[[1, 7, 2], [1, 2, 3], [1, 2, 5], [1, 3, 7], [2, 4, 6], [3, 1, 0], [3, 2, 1]]
- Sorted by reversed plus asc
>>> p.sort(key=lambda x:(-x[0], x[2]))
>>> p
[[13, 1, 0], [3, 2, 1], [2, 4, 6], [1, 2, 3], [1, 2, 5], [1, 3, 7], [-1, 7, 2]]
2. SET:
1) No duplicate
2) No order
3) Sets contain only hashable items, for __contain__ method
4) Sets have operator like "-"
_set = set([1,2,3,3]) # (1,2,3)
s1 = set([1,2,3,4])
s2 = set([2,3,5])
l1 = [1,2,3,4]
l2 = [2,3,5]
s1 - s2
set([1, 4])
l1 - l2
Error
3. Variable length arguments in function call
positional argument with unknown number of arguments
def __func__(*args):
for count, item in enumerate(args):
print '{0}. {1}'.format(count, thing)
named arguments
def __func__(**kwargs):
for name, value in kwargs.items():
print '{0} = {1}' % (name, value)
TCL:
proc __proc__ {first args} {}
4. How to re-import python module in interactive mode
>>> from myrange import *
>>> for i in myrange(1,3,1):
... print i
...
1 <<<<< extra print out due to debug print
1
2
$ more myrange.py
class myrange:
def __init__(self, start, end, step):
self.start = start
self.end = end
self.step = step
print self.step <<<< need to remove this
5. Python class class/instance/internal variables
啥叫class/instance/internal variables?
- classVar 是Object之间share,一个改,大家都改,也叫Static variable
- instanceVar,所以叫Self.instanceVar,就是object自己本地
- internal,就不说了
class Obj(object):
classVar = [10,20,30]
def __init__(self):
self.instanceVar = [1,2,3]
internalVar = [100,200,300]
o1 = Obj()
o2 = Obj()
o1.instanceVar.append(11)
o1.instanceVar.append(12)
o2.instanceVar.append(21)
o2.instanceVar.append(22)
print o1.instanceVar
print o2.instanceVar
o1.classVar.append(111)
o2.classVar.append(222)
print o1.classVar
print o2.classVar
3. Variable length arguments in function call
positional argument with unknown number of arguments
def __func__(*args):
for count, item in enumerate(args):
print '{0}. {1}'.format(count, thing)
named arguments
def __func__(**kwargs):
for name, value in kwargs.items():
print '{0} = {1}' % (name, value)
TCL:
proc __proc__ {first args} {}
4. How to re-import python module in interactive mode
>>> from myrange import *
>>> for i in myrange(1,3,1):
... print i
...
1 <<<<< extra print out due to debug print
1
2
class myrange:
def __init__(self, start, end, step):
self.start = start
self.end = end
self.step = step
print self.step <<<< need to remove this
Change the py file, and do 2 steps
>>> import myrange <<< need to import module for reload()
>>> reload(myrange)
<module 'myrange' from 'myrange.py'>
>>> from myrange import *
>>> for i in myrange(1,3,1):
... print i
...
1 <<<< corrected
2
啥叫class/instance/internal variables?
- classVar 是Object之间share,一个改,大家都改,也叫Static variable
- instanceVar,所以叫Self.instanceVar,就是object自己本地
- internal,就不说了
class Obj(object):
classVar = [10,20,30]
def __init__(self):
self.instanceVar = [1,2,3]
internalVar = [100,200,300]
o1 = Obj()
o2 = Obj()
o1.instanceVar.append(11)
o1.instanceVar.append(12)
o2.instanceVar.append(21)
o2.instanceVar.append(22)
print o1.instanceVar
print o2.instanceVar
o1.classVar.append(111)
o2.classVar.append(222)
print o1.classVar
print o2.classVar
Python Notes (1)
1. Python FAQ:
https://docs.python.org/2.7/faq/programming.html
2. Python module search path
https://docs.python.org/2.7/tutorial/modules.html#the-module-search-path
If you do an "import syslib", how does the python locate the library?
1. local directory <<<< surprised?!
2. PYTHONPATH
so if you have a locally mistaken syslib.py or syslib.pyc under the local directory, you gonna break this import. And if you see something wanky, print cmd.__file__ will be helpful (or cmd.__version__)
3. Python Set
https://docs.python.org/3/tutorial/datastructures.html#sets
https://docs.python.org/2.7/faq/programming.html
2. Python module search path
https://docs.python.org/2.7/tutorial/modules.html#the-module-search-path
If you do an "import syslib", how does the python locate the library?
1. local directory <<<< surprised?!
2. PYTHONPATH
so if you have a locally mistaken syslib.py or syslib.pyc under the local directory, you gonna break this import. And if you see something wanky, print cmd.__file__ will be helpful (or cmd.__version__)
3. Python Set
https://docs.python.org/3/tutorial/datastructures.html#sets
- {} and set() can be used to create set
- But to create an empty one, must use set(), not {} which is to create a dictionary.
- set_ = {0}
4. 3 Ways to delete an element in a list
1) most efficient - del List[idx]
2) less efficient if need to have the element - List.pop(idx)
3) lest effificient - slice, List[:i] + List[i+1:]
5. Python reduce, filter
>>> l = [1,2,3,4]
>>> reduce( (lambda x,y: x*10+y), l)
1234
>>> reduce( (lambda x,y: x*100+y), l)
1020304
>>> l = range(1, 100, 5)
>>> l
[1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76, 81, 86, 91, 96]
>>> filter(lambda x:x%4, l)
[1, 6, 11, 21, 26, 31, 41, 46, 51, 61, 66, 71, 81, 86, 91]
6. Python Naming Convention
http://legacy.python.org/dev/peps/pep-0008/#code-lay-out
2) less efficient if need to have the element - List.pop(idx)
3) lest effificient - slice, List[:i] + List[i+1:]
5. Python reduce, filter
>>> l = [1,2,3,4]
>>> reduce( (lambda x,y: x*10+y), l)
1234
>>> reduce( (lambda x,y: x*100+y), l)
1020304
>>> l = range(1, 100, 5)
>>> l
[1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76, 81, 86, 91, 96]
>>> filter(lambda x:x%4, l)
[1, 6, 11, 21, 26, 31, 41, 46, 51, 61, 66, 71, 81, 86, 91]
6. Python Naming Convention
http://legacy.python.org/dev/peps/pep-0008/#code-lay-out
- limit all lines to 79,docstring/comment to 72
class Rectangle(Blob):
def __init__(self, width, height,
color='black', emphasis=None, highlight=0):
if (width == 0 and height == 0 and
color == 'red' and emphasis == 'strong' or
highlight > 100):
raise ValueError("sorry, you lose")
if width == 0 and height == 0 and (color == 'red' or
emphasis is None):
raise ValueError("I don't think so -- values are %s, %s" %
(width, height))
Blob.__init__(self, width, height,
color, emphasis, highlight)
- Module: short,
- all-lower-case name, like pystock.py
- Class: CapWords, like
- StockHist, StockInfo, StockERHist
- Function:
- lower_case_with_underscore
- Method and instance:
- lower_case_with_underscore
- Constants:
- ALL_CAPITALS_WITH_UNDERSCORE
- Internal attribute:
- _single_leading_underscore
- NOT imported.
- empty sequence = FALSE, so
- YES: if not seq:...
- NO: if len(seq)
- Attributes:
- self.lower_case_with_underscore
9/12/2018
Python Tips
1. Is vs ==, mutable and immutable
>>> id(a)
4463753048 <<<< address is 048
>>> a[0] = 11
>>> id(a)
4463753048
>>> a
[11, 2, 3]
>>> a.append(44)
>>> a
[11, 2, 3, 44]
>>> id(a) <<<< can change item and append, address is same
4463753048
>>> b = a
>>> id(b) <<<< list= is point to same address
4463753048
>>> b[0] = 111
>>> a
[111, 2, 3, 44] <<<< change b = change a
>>> c = a[:]
>>> id(c)
4463919328
>>> c[0] = 1234
>>> a
[111, 2, 3, 44]
>>> b
[111, 2, 3, 44]
>>> c
[1234, 2, 3, 44]
>>>
2. keyword argument
>>> def ff(*args, **kwargs):
... print args
... print kwargs
...
>>> ff(1, '22', k1=333, k2='4444')
(1, '22')
{'k2': '4444', 'k1': 333}
>>> d = {'ka':'aaa', 'kb':123}
>>> ff(**d)
()
{'kb': 123, 'ka': 'aaa'}
3. Regexp \符号
https://docs.python.org/3/howto/regex.html
Remove全部的None-Alphanumeric char from string. 应该是
s = re.sub('\W', '', s)
还有记住以下的
\d, \D = [0-9]
\s, \S = [ \t\n\r\v\f]
\w, \W = alphanumeric,[0-9a-bA-Z_]
4. arstCli Script模版
from arstCliLib import *
import sys
dut = sys.argv[1]
openSshOnDut( dut )
setAccessMethod(dut, 'ssh')
cmd = ['show ip int brief | grep " 10\." | grep Vlan']
output = sendCmd(dut, cmd, prompt='enable', raw=True)
print '\n'.join(output)
[solomonyang@syscon] ~ $ python testCli.py
Traceback (most recent call last):
File "testCli.py", line 4, in <module>
from arstCliLib import *
ImportError: No module named arstCliLib
PATH=$PATH:$HOME/bin:$HOME/py
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/git/systest-infra/lib/
PYTHONPATH=$PYTHONPATH:$HOME/git/systest-infra/lib/
export PATH
export LD_LIBRARY_PATH
export PYTHONPATH
5. List vs Tuple, based on stackoverflow post
2
1
800024
900088
3. Mutable vs Inmutable/可变 vs 不可变
>>> t = (1,2); l = [1,2]
>>> l[0] = 11; print l
[11, 2]
>>> t[0] = 11; print t
TypeError: 'tuple' object does not support item assignment
4. 都可以增加,但是不同,tuple += (3)是返回一个新的obj,而list.add()是改原来的
>>> t = (1,2); l = [1,2]; id(t); id(l); t+=(3,); l+=[3]; id(t); id(l); l.append(3); id(l)
4306859000 <<<<< t
4307014720 <<<<< 1, 都一个地址
4306913952 <<<<< t +=(3,),新地址
4307014720
4307014720
5. 因为不可变,所以tuple (1,2)可以是Dict[key]
>>> d = {}; d[t] = '1,2'
>>> d = {}; d[l] = '1,2'
TypeError: unhashable type: 'list'
6. 用途
比方说,(10,11)是个bookmark,第10页的第11行,一般没有必要改;而list of bookmark = [ (1,10), (10,11), (22, 1)]
7. Tuple != constant list
http://news.e-scribe.com/397
但是这么了解哪,好像也撮合:-) 好像更多的是字面的了解,tuple = lightweight record,比方说:DB API's fetchmany() 返回的是List of tuple. 每个tuple是一个record,不能改其中一项,改了就没有意义了。
List vs Set
1. Literal/语法/内存量
>>> s = set(range(100000)); s.__sizeof__(); l = list(range(100000)); l.__sizeof__()
4194504
900088
2. Set没有Index, 没有重复,可以数学操作 &, -, ^
>>> s1=set(range(1,20,2)); s2=set(range(10,30)); print 's1->', s1; print 's2->', s2; print '-:', s1 - s2; print '&:', s1&s2; s1^s2
s1-> set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
s2-> set([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
-: set([1, 3, 9, 5, 7])
&: set([19, 17, 11, 13, 15])
set([1, 3, 5, 7, 9, 10, 12, 14, 16, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
- == is to compare value, is is compare address
- == is to compare by calling object.__eq__()
- list1 = list2, address is assigned, not value. need list1=list2[:]
>>> id(a)
4463753048 <<<< address is 048
>>> a[0] = 11
>>> id(a)
4463753048
>>> a
[11, 2, 3]
>>> a.append(44)
>>> a
[11, 2, 3, 44]
>>> id(a) <<<< can change item and append, address is same
4463753048
>>> b = a
>>> id(b) <<<< list= is point to same address
4463753048
>>> b[0] = 111
>>> a
[111, 2, 3, 44] <<<< change b = change a
>>> c = a[:]
>>> id(c)
4463919328
>>> c[0] = 1234
>>> a
[111, 2, 3, 44]
>>> b
[111, 2, 3, 44]
>>> c
[1234, 2, 3, 44]
>>>
2. keyword argument
>>> def ff(*args, **kwargs):
... print args
... print kwargs
...
>>> ff(1, '22', k1=333, k2='4444')
(1, '22')
{'k2': '4444', 'k1': 333}
>>> d = {'ka':'aaa', 'kb':123}
>>> ff(**d)
()
{'kb': 123, 'ka': 'aaa'}
3. Regexp \符号
https://docs.python.org/3/howto/regex.html
Remove全部的None-Alphanumeric char from string. 应该是
s = re.sub('\W', '', s)
还有记住以下的
\d, \D = [0-9]
\s, \S = [ \t\n\r\v\f]
\w, \W = alphanumeric,[0-9a-bA-Z_]
4. arstCli Script模版
from arstCliLib import *
import sys
dut = sys.argv[1]
openSshOnDut( dut )
setAccessMethod(dut, 'ssh')
cmd = ['show ip int brief | grep " 10\." | grep Vlan']
output = sendCmd(dut, cmd, prompt='enable', raw=True)
print '\n'.join(output)
[solomonyang@syscon] ~ $ python testCli.py
Traceback (most recent call last):
File "testCli.py", line 4, in <module>
from arstCliLib import *
ImportError: No module named arstCliLib
PATH=$PATH:$HOME/bin:$HOME/py
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/git/systest-infra/lib/
PYTHONPATH=$PYTHONPATH:$HOME/git/systest-infra/lib/
export PATH
export LD_LIBRARY_PATH
export PYTHONPATH
5. List vs Tuple, based on stackoverflow post
1. Literal/语法
>>> t = (1,2); l = [1,2]; t[1]; l[0]2
1
2. Size/内存量,区别大概list +12%
>>> t = tuple(range(100000)); l = list(range(100000)); t.__sizeof__(); l.__sizeof__()800024
900088
3. Mutable vs Inmutable/可变 vs 不可变
>>> t = (1,2); l = [1,2]
>>> l[0] = 11; print l
[11, 2]
>>> t[0] = 11; print t
TypeError: 'tuple' object does not support item assignment
4. 都可以增加,但是不同,tuple += (3)是返回一个新的obj,而list.add()是改原来的
>>> t = (1,2); l = [1,2]; id(t); id(l); t+=(3,); l+=[3]; id(t); id(l); l.append(3); id(l)
4306859000 <<<<< t
4307014720 <<<<< 1, 都一个地址
4306913952 <<<<< t +=(3,),新地址
4307014720
4307014720
5. 因为不可变,所以tuple (1,2)可以是Dict[key]
>>> d = {}; d[t] = '1,2'
>>> d = {}; d[l] = '1,2'
TypeError: unhashable type: 'list'
6. 用途
比方说,(10,11)是个bookmark,第10页的第11行,一般没有必要改;而list of bookmark = [ (1,10), (10,11), (22, 1)]
7. Tuple != constant list
http://news.e-scribe.com/397
但是这么了解哪,好像也撮合:-) 好像更多的是字面的了解,tuple = lightweight record,比方说:DB API's fetchmany() 返回的是List of tuple. 每个tuple是一个record,不能改其中一项,改了就没有意义了。
List vs Set
1. Literal/语法/内存量
>>> s = set(range(100000)); s.__sizeof__(); l = list(range(100000)); l.__sizeof__()
4194504
900088
2. Set没有Index, 没有重复,可以数学操作 &, -, ^
>>> s1=set(range(1,20,2)); s2=set(range(10,30)); print 's1->', s1; print 's2->', s2; print '-:', s1 - s2; print '&:', s1&s2; s1^s2
s1-> set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
s2-> set([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
-: set([1, 3, 9, 5, 7])
&: set([19, 17, 11, 13, 15])
set([1, 3, 5, 7, 9, 10, 12, 14, 16, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
5/11/2018
How to use python/yaml
import yaml
import sys
with open(sys.argv[1], 'r') as stream:
try:
paramDict = yaml.load(stream)
except yaml.YAMLError as err:
print(err)
sys.ext(0)
print paramDict['Devices']['Switch']['mlagA']['Mgmt']['Host']
============
Devices:
Switch:
mlagA: # MLAG Dut1
Mgmt:
Host: bn303
AccessMethod: ssh # ssh or capi
SshUsername: admin # default admin
ChassisType: modular # fixed or modular
CapiProtocol: https
~/py @arst1.sjc> python test.py test.yaml
bn303
import sys
with open(sys.argv[1], 'r') as stream:
try:
paramDict = yaml.load(stream)
except yaml.YAMLError as err:
print(err)
sys.ext(0)
print paramDict['Devices']['Switch']['mlagA']['Mgmt']['Host']
============
Devices:
Switch:
mlagA: # MLAG Dut1
Mgmt:
Host: bn303
AccessMethod: ssh # ssh or capi
SshUsername: admin # default admin
ChassisType: modular # fixed or modular
CapiProtocol: https
~/py @arst1.sjc> python test.py test.yaml
bn303
Subscribe to:
Posts (Atom)