I am trying to do network automation task using python but ran with type error while running the below given script.
I AM STUCK AT SAME KIND OF ERROR, CAN YOU GUYS PLEASE HELP ME OUT HOW TO FIX THIS ?*
durai#durai-virtual-machine:~/Network Automation$ python3 session_details.py
devices list: ['1.1.1.1', '2.2.2.2', '6.6.6.6', '7.7.7.7', '', '']
establishing telnet session: 1.1.1.1 cisco cisco
--- connected to: 1.1.1.1
--- getting version information
Traceback (most recent call last):
File "/home/durai/Network Automation/session_details.py", line 82, in <module>
device_version = get_version_info(session)
File "/home/durai/Network Automation/session_details.py", line 65, in get_version_info
version_output_parts = version_output_lines[1].split(',')
**TypeError: a bytes-like object is required, not 'str'**
durai#durai-virtual-machine:~/Network Automation$
THE BELOW IS THE BLOCK OF CODE WHERE I AM GETTING ERROR !
#-----------------------------------------------------------------------
def get_version_info(session):
print ('--- getting version information')
session.sendline('show version | include Version')
result = session.expect(['>', pexpect.TIMEOUT])
# Extract the 'version' part of the output
version_output_lines = session.before.splitlines()
version_output_parts = version_output_lines[1].split(',')
version = version_output_parts[2].strip()
print ('--- got version: ', version)
return version
#-----------------------------------------------------------------------
FULL CODE FOR YOUR REFERENCE:
#!/usr/bin/python
import re
import pexpect
#-----------------------------------------------------------------------
def get_devices_list():
devices_list = []
file = open('devices', 'r')
for line in file:
devices_list.append( line.rstrip() )
file.close()
print ('devices list:', devices_list)
return devices_list
#-----------------------------------------------------------------------
def connect(ip_address, username, password):
print ('establishing telnet session:', ip_address, username, password)
telnet_command = 'telnet ' + ip_address
# Connect via telnet to device
session = pexpect.spawn('telnet ' + ip_address, timeout=20)
result = session.expect(['Username:', pexpect.TIMEOUT])
# Check for error, if so then print error and exit
if result != 0:
print ('!!! TELNET failed creating session for: ', ip_address)
exit()
# Enter the username, expect password prompt afterwards
session.sendline(username)
result = session.expect(['Password:', pexpect.TIMEOUT])
# Check for error, if so then print error and exit
if result != 0:
print ('!!! Username failed: ', username)
exit()
session.sendline(password)
result = session.expect(['>', pexpect.TIMEOUT])
# Check for error, if so then print error and exit
if result != 0:
print ('!!! Password failed: ', password)
exit()
print ('--- connected to: ', ip_address)
return session
#-----------------------------------------------------------------------
def get_version_info(session):
print ('--- getting version information')
session.sendline('show version | include Version')
result = session.expect(['>', pexpect.TIMEOUT])
# Extract the 'version' part of the output
version_output_lines = session.before.splitlines()
version_output_parts = version_output_lines[1].split(',')
version = version_output_parts[2].strip()
print ('--- got version: ', version)
return version
#-----------------------------------------------------------------------
devices_list = get_devices_list() # Get list of devices
version_file_out = open('version-info-out', 'w')
# Loop through all the devices in the devices list
for ip_address in devices_list:
# Connect to the device via CLI and get version information
session = connect(ip_address, 'cisco', 'cisco')
device_version = get_version_info(session)
session.close() # Close the session
version_file_out.write('IP: '+ip_address+' Version: '+device_version+'\n')
# Done with all devices and writing the file, so close
version_file_out.close()
Python has two different kinds of strings. Normal strings are Unicode, where the individual characters are several bytes long, to handle Unicode characters. Many activities (like networking) need to use byte strings, which are written b"abc".
That's the problem here. The pexpect module is returning a byte string. So, in this line:
version_output_parts = version_output_lines[1].split(',')
version_output_parts is a byte string, but ',' is a Unicode string, and you can't mix them. So, you can either keep it bytes and do this:
version_output_parts = version_output_lines[1].split(b',')
or you can convert it to a Unicode string:
version_output_parts = version_output_parts.decode('utf-8')
version_output_parts = version_output_lines[1].split(b',')
It depends on how much you need to do with the parts.
It's the part where you extract the version that is bugged.
Try using print statements as demonstrated below to check the data types of your variables at each step.
This error suggests that you are using a method that is not available for the given data type e.g. calling a string method on an array or so on.
def get_version_info(session):
print ('--- getting version information')
session.sendline('show version | include Version')
result = session.expect(['>', pexpect.TIMEOUT])
# Extract the 'version' part of the output
version_output_lines = session.before.splitlines()
# print(version_output_lines)
version_output_parts = version_output_lines[1].split(',')
# print(version_output_parts)
version = version_output_parts[2].strip()
# print(version)
print ('--- got version: ', version)
return version
Related
Hi I'm trying to print an sqlite file to a readable format. I'm using dionea honeynet's python script. I encounter this error every time I run the script:
File "./readlogsqltree.py", line 268, in print_logins
login['login_password']))
TypeError: unsupported format string passed to bytes.__format__
The login['login_password'] is a variable taken from a select statement. Here is the function that is being called:
def print_logins(cursor, connection, indent):
r = cursor.execute("""
SELECT
login_username,
login_password
FROM
logins
WHERE connection = ?""", (connection, ))
logins = resolve_result(r)
for login in logins:
print("{:s} login - user:'{:s}' password:'{:s}'".format(
' ' * indent,
login['login_username'],
login['login_password']))
Resolve result function:
def resolve_result(resultcursor):
names = [resultcursor.description[x][0] for x in range(len(resultcursor.description))]
resolvedresult = [ dict(zip(names, i)) for i in resultcursor]
return resolvedresult
Cursor:
def print_db(opts, args):
dbpath = 'logsql.sqlite'
if len(args) >= 1:
dbpath = args[0]
print("using database located at {0}".format(dbpath))
dbh = sqlite3.connect(dbpath)
cursor = dbh.cursor()
I was encountering this error when converting some python2 script to python3:
File "/home/user/Documents/projects/tf-booking/tensorflow-object-detection-example/object_detection_app/app.py", line 152, in encode_image
base64.b64encode(image_buffer.getvalue()))
TypeError: unsupported format string passed to bytes.__format__
Solution was to use base64.b64encode(image_buffer.getvalue()).decode() instead of base64.b64encode(image_buffer.getvalue()) as in this post.
For Python 3, decode the string using decode('utf-8') before calling format()
I have two lists that have user name and password. I want to check which one is correct by iterating through two zipped lists but it isn't working.
Below is the traceback
Traceback (most recent call last):
File "C:\Users\mohamed\Downloads\second_PassWD_Test.py", line 27, in <module>
mme=tn.write(j,i)
TypeError: write() takes exactly 2 arguments (3 given)
Below is the code throwing the exception.
import telnetlib
import re
HOST = "192.168.1.1"
USER = ["admin\n","admin\n","admin"]
PASS = ["cpe#","1234"," "]
try:
tn = telnetlib.Telnet(HOST)
except:
print "Oops! there is a connection error"
frist_log = tn.read_until(":")
if "log" in frist_log:
while 1:
for i,j in zip(USER,PASS):
tn.write(j,i)
break
Telnet.write(buffer) only takes two arguments first is the telnet object and the other is a buffer to send to your session, hence your solution will throw an exception. One way to solve the problem is like a except script using the expect api and use a list of expected output as shown in example below
USER = ["admin\n","admin\n","admin"]
PASS = ["cpe#","1234"," "]
prompt = "#" ## or your system prompt
tn = telnetlib.Telnet(HOST)
first_log = tn.read_until(":")
for user,password in zip(USER,PASS):
try:
tn.write(user)
tn.expect([":"],timeout = 3) # 3 second timeout for password prompt
tn.write(password+"\n")
index,obj,string = tn.expect([":",prompt],timeout = 3)
found = string.find(prompt)
if found >= 0:
break # found the username password match break
###else continue for next user/password match
except:
print "exception",sys.exc_info()[0]
For my IRC bot when I try to use the `db addcol command I will get that Index error but I got no idea what is wrong with it.
#hook.command(adminonly=True, autohelp=False)
def db(inp,db=None):
split = inp.split(' ')
action = split[0]
if "init" in action:
result = db.execute("create table if not exists users(nick primary key, host, location, greeting, lastfm, fines, battlestation, desktop, horoscope, version)")
db.commit()
return result
elif "addcol" in action:
table = split[1]
col = split[2]
if table is not None and col is not None:
db.execute("ALTER TABLE {} ADD COLUMN {}".format(table,col))
db.commit
return "Added Column"
That is the command I am trying to execute and here is the error:
Unhandled exeption in thread started by <function run at 0xb70d6844
Traceback (most recent call last):
File "core/main.py", line 68, in run
out = func(input.inp, **kw)
File "plugins/core_admin_global.py", :ine 308, in db
col = split[2]
IndexError: list index out of range
You will find the whole code at my GIT repository.
Edit: This bot is just a little thing I have been playing around with while learning python so don't expect me to be too knowledgeable about this.
Yet another edit:
The command I am trying to add, just replace desktop with mom.
#hook.command(autohelp=False)
def desktop(inp, nick=None, conn=None, chan=None,db=None, notice=None):
"desktop http://url.to/desktop | # nick -- Shows a users Desktop."
if inp:
if "http" in inp:
database.set(db,'users','desktop',inp.strip(),'nick',nick)
notice("Saved your desktop.")
return
elif 'del' in inp:
database.set(db,'users','desktop','','nick',nick)
notice("Deleted your desktop.")
return
else:
if '#' in inp: nick = inp.split('#')[1].strip()
else: nick = inp.strip()
result = database.get(db,'users','desktop','nick',nick)
if result:
return '{}: {}'.format(nick,result)
else:
if not '#' in inp: notice(desktop.__doc__)
return 'No desktop saved for {}.'.format(nick)
I am trying to create a Python program that will query a URL and produce a JSON file. I need to pass an argument in the end of the URL which comes from the SQL query.
I have imported the requests library.
I get an error message 'TypeError: float argument required, not str' when I am trying to pass argument in the URL.
There is only one column of result produced from the query:
id
2
3
4
Below is what I came up with:
import MySQLdb
import requests
con=MySQLdb.connect(host="localhost",user="test", passwd="test", db ="mfg")
cur = con.cursor()
select=("select id from tblMfg")
cur.execute(select)
result=cur.fetchall()
for i in result:
col =i[0]
col1=str(col)
url = 'http://appl.xyz.net:8080/app/content/pq/doQuery?solution=nd&path=&file=Test.nd&dataAccessId=1¶mid=%d' % col1
user = 'abc'
password ='testgo'
data = requests.get(url, auth=(user, password))
json_data=data.json()
print json_data
Leave creating parameters to the requests framework instead:
params = {'solution': 'nd', 'path': '', 'file': 'Test.nd', 'dataAccessId': '1',
'paramid': str(col[0])}
url = 'http://appl.xyz.net:8080/app/content/pq/doQuery'
user = 'abc'
password ='testgo'
data = requests.get(url, auth=(user, password), params=params)
The error message 'TypeError: float argument required, not str' also occurs when you try to format a string containing an (accidental) naked percent sign.
Example:
>>> print "fail 100% for serverid|%s| " % ("a")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: float argument required, not str
>>>
The "f" after the "100% " is interpreted as asking for a floating point argument, whereas it was simply my smudgefingers leaving off the second percent sign.
>>> print "fail 100%% for serverid|%s| " % ("a")
fail 100% for serverid|a|
>>>
works fine. If the word following the "100% " begins with d or o or s, you get slightly different error messages.
I was unlucky enough to have this happen several call layers inside a 2-nested try-except, so the error showed up a mile away from the line that caused it.
print ("float_value : %f , digit_value : %d , string_value : %s" % (3.4, 5, 'somestring'))
float_value : 3.400000 , digit_value : 5 , string_value : somestring
I have a DNS script which allow users to resolve DNS names by typing website names on a Windows command prompt.
I have looked through several guides on the DNS resolve but my script can't still seem to resolve the names (www.google.com) or (google.com) to IP address.
The script outputs an error of
Traceback (most recent call last):
File "C:\python\main_menu.py", line 37, in ?
execfile('C:\python\showdns.py')
File "C:\python\showdns.py", line 3, in ?
x = input ("\nPlease enter a domain name that you wish to translate: ")
File "<string>", line 0, in ?
NameError: name 'google' is not defined
The code:
import socket
x = input ("\nPlease enter a domain name that you wish to translate: ")
print ("\n\nThe IP Address of the Domain Name is: "+socket.gethostbyname_ex(x))
x = raw_input("\nSelect enter to proceed back to Main Menu\n")
if x == '1':
execfile('C:\python\main_menu.py')
Please give advice on the codes. Thanks!
input() is the wrong function to use here. It actually evaluates the string that the user entered.
Also gethostbyname_ex returns more than just a string. So your print statement would also have failed.
In your case this code should work:
import socket
x = raw_input ("\nPlease enter a domain name that you wish to translate: ")
data = socket.gethostbyname_ex(x)
print ("\n\nThe IP Address of the Domain Name is: "+repr(data))
x = raw_input("\nSelect enter to proceed back to Main Menu\n")
if x == '1':
execfile('C:\python\main_menu.py')
#!/user/bin/env python
"""
Resolve the DNS/IP address of a given domain
data returned is in the format:
(name, aliaslist, addresslist)
#filename resolveDNS.py
#version 1.01 (python ver 2.7.3)
#author LoanWolffe
"""
import socket
def getIP(d):
"""
This method returns the first IP address string
that responds as the given domain name
"""
try:
data = socket.gethostbyname(d)
ip = repr(data)
return ip
except Exception:
# fail gracefully!
return False
#
def getIPx(d):
"""
This method returns an array containing
one or more IP address strings that respond
as the given domain name
"""
try:
data = socket.gethostbyname_ex(d)
ipx = repr(data[2])
return ipx
except Exception:
# fail gracefully!
return False
#
def getHost(ip):
"""
This method returns the 'True Host' name for a
given IP address
"""
try:
data = socket.gethostbyaddr(ip)
host = repr(data[0])
return host
except Exception:
# fail gracefully
return False
#
def getAlias(d):
"""
This method returns an array containing
a list of aliases for the given domain
"""
try:
data = socket.gethostbyname_ex(d)
alias = repr(data[1])
#print repr(data)
return alias
except Exception:
# fail gracefully
return False
#
# test it
x = raw_input("Domain name or IP address? > ")
a = getIP(x)
b = getIPx(x)
c = getHost(x)
d = getAlias(x)
print " IP ", a
print " IPx ", b
print " Host ", c
print " Alias ", d
Use raw_input instead of input.