[Tutor] Simple Python Telnet Client (Help with Asynchronous IO)

2010-08-03 Thread Nathan Farrar
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

2009-10-20 Thread Nathan Farrar
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

2009-10-20 Thread Nathan Farrar
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

2009-10-16 Thread Nathan Farrar
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

2008-07-05 Thread Nathan Farrar
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

2008-07-05 Thread Nathan Farrar
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