[Tutor] Simple Python Telnet Client (Help with Asynchronous IO)
Hello All, I'm attempting to write a simple telnet client. Yes, I've been told that I should be using twisted to do this. I want to learn to do it myself first, so that I can fully understand the concepts - then I will scrap it and switch to using twisted. When I started, I didn't realize there was such a thing as blocking IO. I assumed that if I put the read/write calls for stdio the socket in different threads all would be good. I've been told that this is not the case and that if I perform a blocking IO call in a thread (such as sys.stdin.read()) it will halt the execution of all threads in the process. I found an example that uses the select module to see if any data is available from stdin before attempting to read ... and that this is the asynchronous/non-blocking way to do it. I've implemented this code, but I can't figure out a similar way to do this with the socket. Here's the code I've put together so far: #!/usr/bin/env python import collections import os import select import socket import sys import termios import tty import threading class InputThread(threading.Thread): Read data from the stdin and place in the input buffer. def __init__(self, input_buffer): threading.Thread.__init__(self) self.input_buffer = input_buffer def run(self): self.old_settings = termios.tcgetattr(sys.stdin) tty.setcbreak(sys.stdin.fileno()) # prompt loop try: while True: if select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []): self.input_buffer.append(sys.stdin.read()) print finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.old_settings) class DisplayThread(threading.Thread): Check ouput buffer for data. Print and data and flush buffer. def __init__(self, output_buffer): threading.Thread.__init__(self) self.output_buffer = output_buffer def run(self): while True: while len(self.output_buffer) 0: output_data = self.output_buffer.pop() print output_data, class SocketThread(threading.Thread): Check input buffer. If data exists, send it to socket. Read any incoming data from socket and place it in output buffer. def __init__(self, input_buffer, output_buffer): threading.Thread.__init__(self) self.input_buffer = input_buffer self.output_buffer = output_buffer def run(self): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setblocking(1) self.socket.connect(('nannymud.lysator.liu.se',2000)) while True: while len(self.input_buffer) 0: input_data = self.input_buffer.pop() self.socket.send(input_data, '\n') self.output_buffer.append(self.socket.recv(1024)) self.sock.close() def main(): Interactive, multithreaded network client written in python. print Use 'quit' to exit client. input_buffer = collections.deque() output_buffer = collections.deque(); input_thread = InputThread(input_buffer) input_thread.start() display_thread = DisplayThread(output_buffer) display_thread.start() socket_thread = SocketThread(input_buffer, output_buffer) socket_thread.start() if __name__ == '__main__': main() Help sorting this out so that I can fully understand the concepts and get this working would be greatly appreciated. As I mentioned previously, I am fully planning on scrapping this and rewriting it using twisted once I understand the concepts and have a working prototype. Thank you! - F4RR4R -- Science replaces private prejudice with publicly verifiable evidence. - Richard Dawkins ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pexpect maxread searchwindowsize, timeout
I haven't been able to find any real examples of pexpect usage, nor documentation. Just little bits here and there, so I'm kind of struggling through. I've got the follow bit of code I'm working with: def main(): try: print 'attempting to spawn connection ... ' session = pexpect.spawn('ssh usern...@x.x.x.x') except: print 'couldn\'t spawn connection ... ' print 'waiting for password prompt ... ' session.expect('password:') print 'received password prompt ... ' try: print 'attempting to send password ... ' session.sendline(password) except: print 'error sending password ... ' print 'waiting for command prompt ... ' session.expect(command_prompt) print 'received command prompt ... ' try: print 'attempting to issue \'show version\' command ... ' session.sendline([expect.TIMEOUT=1, 'show version']) except: print 'error issuing \'show version\' command ... ' print 'waiting for command prompt ... ' session.expect(command_prompt) print 'received command prompt ... ' print 'attempting to print command results ... ' print session.before print 'closing session ... ' session.close() if __name__=='__main__': main() When I run this against a cisco device, it times out waiting for the command prompt after issuing the show version command. However, if I change 'show version' to something like 'blah blah' it doesn't time out, and I get the results of the command (an error message that is much shorter in length). I believe that the results of the show version command are simply too large. I think I may need to increase the size of maxread searchwindowsize set the timeout to something lower than the default, but I haven't been able to figure out how to do this correctly yet. Any help would be greatly appreciated. I'm pulling my hair out. Thank you. -- The presence of those seeking the truth is infinitely to be preferred to the presence of those who think they've found it. –Terry Pratchett ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pexpect maxread searchwindowsize, timeout
Thanks! That solves my question about configuring the timeout value. However - I still have the problem (I believe) that by default, I can handle all the output. When I issue the show version it fails, but if I issue a command with less data returned it succeeds. In the documentation I can see that pexpect uses a maxread and a searchwindowsize value, but I'm not sure how to use them. Any tips? Thanks again. On Tue, Oct 20, 2009 at 11:26 AM, vince spicer vinces1...@gmail.com wrote: On Tue, Oct 20, 2009 at 11:11 AM, Nathan Farrar nathan.far...@gmail.com wrote: I haven't been able to find any real examples of pexpect usage, nor documentation. Just little bits here and there, so I'm kind of struggling through. I've got the follow bit of code I'm working with: def main(): try: print 'attempting to spawn connection ... ' session = pexpect.spawn('ssh usern...@x.x.x.x') except: print 'couldn\'t spawn connection ... ' print 'waiting for password prompt ... ' session.expect('password:') print 'received password prompt ... ' try: print 'attempting to send password ... ' session.sendline(password) except: print 'error sending password ... ' print 'waiting for command prompt ... ' session.expect(command_prompt) print 'received command prompt ... ' try: print 'attempting to issue \'show version\' command ... ' session.sendline([expect.TIMEOUT=1, 'show version']) except: print 'error issuing \'show version\' command ... ' print 'waiting for command prompt ... ' session.expect(command_prompt) print 'received command prompt ... ' print 'attempting to print command results ... ' print session.before print 'closing session ... ' session.close() if __name__=='__main__': main() When I run this against a cisco device, it times out waiting for the command prompt after issuing the show version command. However, if I change 'show version' to something like 'blah blah' it doesn't time out, and I get the results of the command (an error message that is much shorter in length). I believe that the results of the show version command are simply too large. I think I may need to increase the size of maxread searchwindowsize set the timeout to something lower than the default, but I haven't been able to figure out how to do this correctly yet. Any help would be greatly appreciated. I'm pulling my hair out. Thank you. -- The presence of those seeking the truth is infinitely to be preferred to the presence of those who think they've found it. –Terry Pratchett ___ Tutor maillist - tu...@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor Looks like you are trying to end multiple commands to the sendline and not expect you can specify the timeout on the expect line try this code: # def main(): try: print 'attempting to spawn connection ... ' session = pexpect.spawn('ssh usern...@x.x.x.x') except: print 'couldn\'t spawn connection ... ' print 'waiting for password prompt ... ' session.expect('password:') print 'received password prompt ... ' try: print 'attempting to send password ... ' session.sendline(password) except: print 'error sending password ... ' print 'waiting for command prompt ... ' session.expect(command_prompt) print 'received command prompt ... ' try: print 'attempting to issue \'show version\' command ... ' session.sendline('show version') #: send only command except: print 'error issuing \'show version\' command ... ' print 'waiting for command prompt ... ' session.expect(command_prompt, timeout=1) #: set the timeout here print 'received command prompt ... ' print 'attempting to print command results ... ' print session.before print 'closing session ... ' session.close() if __name__=='__main__': main() #== Vince -- The presence of those seeking the truth is infinitely to be preferred to the presence of those who think they've found it. –Terry Pratchett ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Help with pexpect
I'm trying to automate the collection of data to remote devices over ssh via pexpect. I had originally attempted (with limited success) to use paramiko, however due to cisco's ssh implimentation I cannot send mulitple commands over the same connection, which is absolutely essential. Therefore, I'm now attempting to use pexpect, but am having trouble getting started. I have a simple script, such as: session = pexpect.spawn('ssh u...@host') session.expect([pexpect.TIMETOUT, 'password:']) session.send('password') print session.read() # shouldn't this display the logon banner command prompt? session.close() This code results in no output a hanging window. What am I doing incorrect? Additionally, I will need to add conditional pexpect statements, such that when I execute a command I want to gather the output, however if '--More--' is encountered (and it this can happen multiple times), I want to send a newline character to the session and continue gathering the output. Thanks for the help! Nathan -- The presence of those seeking the truth is infinitely to be preferred to the presence of those who think they've found it. –Terry Pratchett ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Script Name/Path Information
I'm new to python and wondering if there is a way to reference information about the script that is running. For example, if I was running a script named FileInfo.py from the directory /home/username, I'm looking for attributes such that something similar to: print self.name print self.path would output: FileInfo.py /home/username ... Thanks! Nathan ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Exploring the Standard Library
I'd like to spend some time exploring the standard library. I'm running python on Ubuntu. How would I find the location of the modules (find / -name os.py does not yield results)? Thanks! Nathan ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor