pythonpexpectremote-connection

Establishing connection using pexpect


I am trying to establish a connection using pexpect with below approach-

child = pexpect.spawn('telnet {console_ip} {console_port}'.format(console_ip=self.obj.get("console_ip"),
                                                                      console_port=int(self.obj.get("console_port"))))
while True:
        index = child.expect(
            ["Hit 'c' key to stop autoboot:", "prompt#", "ARGUS", "Loading:", ".*login:", "Escape character is",
             "Press \[Ctrl+D\] to go to the Suspend Menu", "Please enter your name:"])
        if index == 0:
            child.sendline("ccccc\n")
        elif index == 1:
            time.sleep(1)
            child.sendline("\r run net \r")
            time.sleep(1)
        elif index == 2:
            time.sleep(1)
            child.sendline("\r reset \r")
            time.sleep(5)
        elif index == 3:
            time.sleep(1)
            time.sleep(3)
            break
        elif index == 4:
            child.sendline(user_name+"\r")
        elif index == 5:
            time.sleep(1)
            child.sendline(password+"\r")
        elif index == 6:
            time.sleep(1)
            child.sendline("\r")
        elif index == 7:
            time.sleep(1)
            child.sendline("\r")
        elif index == 8:
            time.sleep(1)
            child.sendline("abcde\r")

I want to know if there is any better way to implement the same with less line of code.


Solution

  • Reducing the number of lines should not be an imperative, but trying to provide structure and reduce repetition might be. It would nice to have the prompt string and its corresponding action closer together. You could for example, pair up into a tuple the prompt "Hit 'c' key...", and the sendline string reply "ccccc\n", and then create an array of all these. You might then be able to remove the if's and have a common action calling sendline on the indexed tuple.

    But as soon as you start moving this way, it is often best to go all the way and create a simple class to consolidate the prompt, the reply, and other parts of the action. Eg

    class match:
        def __init__(self, match, response, before=1, after=0, stop=False):
            self.match = match
            self.response = response
            self.before = before
            self.after = after
            self.stop = stop
    
        def action(self):
            time.sleep(self.before)
            child.sendline(self.response)
            time.sleep(self.after)
            return self.stop
    
    matches = [
        match("Hit 'c' key to stop autoboot:", "ccccc\n", 0),
        match("prompt#", "\r run net \r", after=1),
        match("ARGUS", "\r reset \r", after=5),
        ... 
    ]
    tomatch = [m.match for m in matches]
    while True:
        index = child.expect(tomatch)
        if matches[index].action():
            break