Client connect issue with adding error handling - python

I am trying to connect to an account on Splunk via Python and Bash. I can connect to the website fine and it prints what I want it to, in the terminal, when I log in correctly. However when I use the wrong log in details, it prints a large error message saying 'login failed' that I want to try and condense to one line only.
This is what I am using to connect to Splunk:
service = client.connect(
host=splunk_config['host'],
port=splunk_config['port'],
username=splunk_config['username'],
password=splunk_config['password'])
I want to do something along the lines of:
if (service errors):
print ("Failed to connect")
else:
print ("Successfully connected")

Without the exception and guessing you're using splunklib I would imagine you need something like:
try:
service = client.connect(
host=splunk_config['host'],
port=splunk_config['port'],
username=splunk_config['username'],
password=splunk_config['password'])
print("Login succesfull")
except splunklib.binding.AuthenticationError as e:
print("Login failed")

Related

try except not running except part

I have a short code that ftps a small file into a server.
session = ftplib.FTP("192.168.0.164", "admin", "admin")
file = open("path/test.txt", "rb")
try:
session.storbinary("STOR application/test.txt", file)
except:
print("failed")
else:
print("success!")
file.close()
In the above piece I changed the IP address to so it would fail (there is no 192.168.0.164 device) and it doesn't print failed like it's supposed to. In the terminal I get a
"connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond" error.
if I mistype the path, I also don't get a failed print on the terminal.
If I type in the correct IP the success part does work.
Am I using the try/except wrong?
UPDATE:
Current code looks like this:
file = open("path/test.txt", "rb")
try:
session = ftplib.FTP("192.168.0.161", "admin", "admin")
session.storbinary("STOR application/test.txt", file)
except:
print("Unable to reach host")
else:
print("success!")
session.quit()
finally:
print ("DONE!!")
file.close()
I figure the ftplib.all_errors will catch all errors (host unreachable, and file not found). It seems to catch the unable to reach host errors, but no file not found errors.
Am I using the try/except wrong?
Your syntax is correct, but Python is not actually reaching the try block at all.
When you call session = ftplib.FTP(host, ...) where host is unreachable, the code will stop in its tracks there. That's because FTP.__init__() greedily calls self.connect(). This will in turn call socket.create_connection(), which will not succeed for an unreachable host.
So, you'd need to modify to:
with open("path/test.txt", "rb") as file:
try:
session = ftplib.FTP("192.168.0.164", "admin", "admin")
session.storbinary("STOR application/test.txt", file)
except Exception as e:
print("failed")
print(e)
else:
print("success!")
finally:
session.quit()

Retaining an SSH session across multiple API calls

So interesting situation here. Currently I have a simple Flask API that connects to a network device on the backend and retrieves command output.
from netmiko import ConnectHandler
def _execute_cli(self, opt, command):
"""
Internal method to create netmiko connection and
execute command.
"""
try:
net_connect = ConnectHandler(**opt)
cli_output = (net_connect.send_command(command))
except (NetMikoTimeoutException, NetMikoAuthenticationException,) as e:
reason = e.message
raise ValueError('Failed to execute cli on %s due to %s', opt['ip'], reason)
except SSHException as e:
reason = e.message
raise ValueError('Failed to execute cli on %s due to %s', opt['ip'], reason)
except Exception as e:
reason = e.message
raise ValueError('Failed to execute cli on %s due to %s', opt['ip'], reason)
return cli_output
def disconnect(connection):
connection.disconnect()
Each command output is cached locally for a period of time. The problem is, someone could make multiple connections simultaneously, and a device has a connection limit (Let's say 7). What happens is if too many calls are made, an SSH connection issue occurs because max connections have been reached.
What I'm looking to do is retain a single session across these API calls for a device for a specified period of time (Let's say, 5 minutes), and that way I'm not filling up the connections on the device.
Please advise.
Ok i am not sure what did you mean by "retain a single session across these API calls". But maybe you can do something like this.
Create a dictionary for all devices and and their user amount in every 5 min. for example:
self.users = {device:0 for device in devices}
and then whenever _execute_cli() function called, you can check the amount of users in device before sending commands(in cisco the command is 'show users') and update the variable self.users[device] = some_number.
So you can simply check like like:
if self.users[device] < 7:
try:
net_connect = ConnectHandler(**opt)
cli_output = (net_connect.send_command(command))
...

how to read the pop server response in python

I am trying to read the response or exception of pop3 hotmail server. its very simple question but i am beginner in python don't know how to read it? this is my code:
import poplib
import sys
host = 'pop3.live.com'
port = 995
email='123456#hotmail.com'
pwd='123456'
server = poplib.POP3_SSL(host, port)
try:
server.user(email)
server.pass_(pwd)
if('+OK'):
print 'Email: '+email+'password: '+pwd
server.quit()
sys.exit(1)
except poplib.error_proto:
if('POP+disabled'):
print 'Email: '+email+'password: '+pwd
server.quit()
sys.exit(1)
elif('authentication+failed'):
print "wronge user and pass. try again"
continue
continue
in exception "if ('POP+disabled')" used to eliminate that user login and password is correct but the account has not enabled POP3 in options.
when I run the above code then it also display email password whether i put wrong password...
Can any body help me please how to handle this problem?
You can use the server.getwelcome() method to check for the server response before proceeding into parsing messages.
The server object lets you request the list of messages after authentication and then you can call retr to retrieve each message.
welcomeresp = server.getwelcome()
if welcomeresp.find("+OK"):
numMessages = len(server.list()[1])
for i in range(numMessages):
for j in server.retr(i+1):
server_msg, body, octets = j
for line in body:
print line
Take a look at the documentation for the POP library for more information and an example:
https://docs.python.org/2/library/poplib.html

Resume FTP download after timeout

I'm downloading files from a flaky FTP server that often times out during file transfer and I was wondering if there was a way to reconnect and resume the download. I'm using Python's ftplib. Here is the code that I am using:
#! /usr/bin/python
import ftplib
import os
import socket
import sys
#--------------------------------#
# Define parameters for ftp site #
#--------------------------------#
site = 'a.really.unstable.server'
user = 'anonymous'
password = 'someperson#somewhere.edu'
root_ftp_dir = '/directory1/'
root_local_dir = '/directory2/'
#---------------------------------------------------------------
# Tuple of order numbers to download. Each web request generates
# an order numbers
#---------------------------------------------------------------
order_num = ('1','2','3','4')
#----------------------------------------------------------------#
# Loop through each order. Connect to server on each loop. There #
# might be a time out for the connection therefore reconnect for #
# every new ordernumber #
#----------------------------------------------------------------#
# First change local directory
os.chdir(root_local_dir)
# Begin loop through
for order in order_num:
print 'Begin Proccessing order number %s' %order
# Connect to FTP site
try:
ftp = ftplib.FTP( host=site, timeout=1200 )
except (socket.error, socket.gaierror), e:
print 'ERROR: Unable to reach "%s"' %site
sys.exit()
# Login
try:
ftp.login(user,password)
except ftplib.error_perm:
print 'ERROR: Unable to login'
ftp.quit()
sys.exit()
# Change remote directory to location of order
try:
ftp.cwd(root_ftp_dir+order)
except ftplib.error_perm:
print 'Unable to CD to "%s"' %(root_ftp_dir+order)
sys.exit()
# Get a list of files
try:
filelist = ftp.nlst()
except ftplib.error_perm:
print 'Unable to get file list from "%s"' %order
sys.exit()
#---------------------------------#
# Loop through files and download #
#---------------------------------#
for each_file in filelist:
file_local = open(each_file,'wb')
try:
ftp.retrbinary('RETR %s' %each_file, file_local.write)
file_local.close()
except ftplib.error_perm:
print 'ERROR: cannot read file "%s"' %each_file
os.unlink(each_file)
ftp.quit()
print 'Finished Proccessing order number %s' %order
sys.exit()
The error that I get:
socket.error: [Errno 110] Connection timed out
Any help is greatly appreciated.
Resuming a download through FTP using only standard facilities (see RFC959) requires use of the block transmission mode (section 3.4.2), which can be set using the MODE B command. Although this feature is technically required for conformance to the specification, I'm not sure all FTP server software implements it.
In the block transmission mode, as opposed to the stream transmission mode, the server sends the file in chunks, each of which has a marker. This marker may be re-submitted to the server to restart a failed transfer (section 3.5).
The specification says:
[...] a restart procedure is provided to protect users from gross system failures (including failures of a host, an FTP-process, or the underlying network).
However, AFAIK, the specification does not define a required lifetime for markers. It only says the following:
The marker information has meaning only to the sender, but must consist of printable characters in the default or negotiated language of the control connection (ASCII or EBCDIC). The marker could represent a bit-count, a record-count, or any other information by which a system may identify a data checkpoint. The receiver of data, if it implements the restart procedure, would then mark the corresponding position of this marker in the receiving system, and return this information to the user.
It should be safe to assume that servers implementing this feature will provide markers that are valid between FTP sessions, but your mileage may vary.
A simple example for implementing a resumable FTP download using Python ftplib:
def connect():
ftp = None
with open('bigfile', 'wb') as f:
while (not finished):
if ftp is None:
print("Connecting...")
FTP(host, user, passwd)
try:
rest = f.tell()
if rest == 0:
rest = None
print("Starting new transfer...")
else:
print(f"Resuming transfer from {rest}...")
ftp.retrbinary('RETR bigfile', f.write, rest=rest)
print("Done")
finished = True
except Exception as e:
ftp = None
sec = 5
print(f"Transfer failed: {e}, will retry in {sec} seconds...")
time.sleep(sec)
More fine-grained exception handling is advisable.
Similarly for uploads:
Handling disconnects in Python ftplib FTP transfers file upload
To do this, you would have to keep the interrupted download, then figure out which parts of the file you are missing, download those parts and then connect them together. I'm not sure how to do this, but there is a download manager for Firefox and Chrome called DownThemAll that does this. Although the code is not written in python (I think it's JavaScript), you could look at the code and see how it does this.
DownThemll - http://www.downthemall.net/

Socket connection to a telnet-based server hangs on read

I'm trying to write a simple socket-based client in Python that will connect to a telnet server. I can test the server by telnetting to its port (5007), and entering text. It responds with a NAK (error) or an AK (success), sometimes accompanied by other text. Seems very simple.
I wrote a client to connect and communicate with the server, but it hangs on the first attempt to read the response. The connection is successful. Queries like getsockname and getpeername are successful. The send command returns a value that equals the number of characters I'm sending, so it seems to be sending correctly. But in the end, it always hangs when I try to read the response.
I've tried using both file-based objects like readline and write (via socket.makefile), as well as using send and recv. With the file object I tried making it with "rw" and reading and writing via that object, and later tried one object for "r" and another for "w" to separate them. None of these worked.
I used a packet sniffer to watch what's going on. I'm not versed in all that I'm seeing, but during a telnet session I can see my typed text and the server's text coming back. During my Python socket connection, I can see my text going to the server, but packets back don't seem to have any text in them.
Any ideas on what I'm doing wrong, or any strategies to try?
Here's the code I'm using (in this case, it's with send and recv):
#!/usr/bin/python
host = "localhost"
port = 5007
msg = "HELLO EMC 1 1"
msg2 = "HELLO"
import socket
import sys
try:
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
print("Error creating socket: %s" % e)
sys.exit(1)
try:
skt.connect((host,port))
except socket.gaierror, e:
print("Address-related error connecting to server: %s" % e)
sys.exit(1)
except socket.error, e:
print("Error connecting to socket: %s" % e)
sys.exit(1)
try:
print(skt.send(msg))
print("SEND: %s" % msg)
except socket.error, e:
print("Error sending data: %s" % e)
sys.exit(1)
while 1:
try:
buf = skt.recv(1024)
print("RECV: %s" % buf)
except socket.error, e:
print("Error receiving data: %s" % e)
sys.exit(1)
if not len(buf):
break
sys.stdout.write(buf)
Oh, in case it's useful, here's an example telnet session done manually:
ubuntu:~/mac/python$ telnet localhost 5007
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HELLO EMC 1 1
HELLO ACK EMCNETSVR 1.1
The first 'HELLO' line is what I typed, the second one is the response.
You probably need to terminate your msg with some kind of "line-ending characters" -- perhaps \r\n, perhaps just one of the two. When you're in telnet, didn't you terminate your typed text by hitting a Return or Enter key? In the Python code, you're not doing the equivalent of that.
You need to flush the socket right after the send, to force the TCP stack to actually send the data. Otherwise it will wait for more data to send, in order to fill a packet effectively. While you are waiting for a response from the server nothing has actually been sent yet.

Categories