pythonautomationexpectpexpect

expect: make two python scripts communicate


I want to have two scripts communicating by exchanging messages. I have to use pexpect because of other restrictions. I am trying to make a minimal working example before I build it out for my application.

I have tried to do a minimal working example by following the tutorials I could find on the internet. But I've failed and here is my attempt.The first script is the one that initiates communication:

#script_1.py

import pexpect

p = pexpect.spawn("python /path/to/script/script_2.py")
p.expect(">")
p.sendline(input("Message to the other script: "))
print( p.before )

Here is the second script which should receive communication and send answer:

#script_2.py

indata = input(">") 
print(indata)

How can I make two python scripts communicate by using pexpect?


EDIT: I was asked why I say that the scripts fail given that there are no error messages. The reason it is a failure is that script 2 should echo the message sent by script 1, and script 1 should print out (or in other ways capture the response), but that doesn't happen


Solution

  • Your difficulty revolves around buffering of the > prompt. The 2nd script does not quickly send it, so the 1st script doesn't see it.

    Let us alter the scripts slightly, so they look like this. And assume the user types in "apples".

    script_2.py

    print("ok1")
    indata = input(">")
    print("I like", indata, ".")
    print("ok2")
    

    script_1.py

    import pexpect
    
    p = pexpect.spawn("python /path/to/script_2.py")
    
    p.expect("ok1")
    assert p.before == b""
    assert p.after == b"ok1"
    p.sendline(input("Message to the other script: "))
    
    p.expect("ok2")
    assert p.before == b"\r\n>apples\r\nI like apples .\r\n"
    assert p.after == b"ok2"
    assert p.buffer == b"\r\n"
    

    (I started out with just "ok", then realized I needed two distinct strings.)

    What is different, here? The print() with a newline is flushing the buffer to stdout, so that script_1 has an opportunity to see the string it is looking for.