Getting Started

Installation

streamexpect may be installed directly from PyPi using pip:

pip install streamexpect

This will install the library as well as any dependency libraries.

The library is tested to work on the following Python versions:

  • Python 2.7
  • Python 3.3
  • Python 3.4
  • Python 3.5
  • PyPy
  • PyPy3

The streamexpect.wrap Function

streamexpect provides a convenience function that does much of the setup and configuration of the streamexpect types, returning to the user an easy-to-use wrapper over the provided stream. A common use case is communicating with a remote socket using a simple text-based protocol. In this case, we’ll use streamexpect to talk to Google:

import socket
import streamexpect

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('www.google.com', 80))

# By default, this will open in binary mode. To read a non-ASCII text stream,
# the unicode option needs to be enabled.
with streamexpect.wrap(sock) as stream:

    # Send the request. This is passed to the underlying socket.
    stream.sendall(b'GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n')

    # Find the start of the response.
    stream.expect_bytes(b'HTTP/1.1 200 OK\r\n')

    # Find the "Date" header using regex groups and print it.
    match = stream.expect_regex(br'Date: ([^\r\n]+)\r\n')
    print(u'Google says the date/time is ' + match.groups[0].decode('ascii'))

streamexpect also provides intelligent support for Unicode in both Python 2 and Python 3. When using the streamexpect.wrap() function, all that is needed to enable Unicode support is the unicode=True flag:

import io
import streamexpect

unicode_stream = io.StringIO(u'¡Se puede con español!')

with streamexpect.wrap(unicode_stream, unicode=True) as stream:
    match = stream.expect_text(u'español')
    assert match is not None
    print(u'Found {} at index {}'.format(match.match, match.start))

Another common streamexpect use case is for interacting with PySerial. Since streamexpect does not require that the underlying stream define an actual file, it is even possible to use streamexpect with PySerial on Windows!

# Send the uname command to a Linux PC connected to a Windows PC over serial
import serial
import streamexpect

# timeout=0 is essential, as streams are required to be non-blocking
ser = serial.Serial('COM1', baudrate=115200, timeout=0)

with streamexpect.wrap(ser) as stream:
    stream.write(b'\r\nuname -a\r\n')
    match = stream.expect_bytes(b'Linux', timeout=1.0)
    print(u'Found Linux at index {}'.format(match.start))

Text vs. Binary

Much like Python 3, streamexpect takes a very explicit stance on what is text and what is binary. This position carries over to streamexpect even when used with Python 2, and therefore may catch some users unaware.

Simply stated, if a stream type returns the str type in Python 2 or the bytes type in Python 3, it is treated as a binary stream. In this case, only binary may be provided to the Expecter.expect() method. Likewise, if a stream type returns the unicode type in Python 2 or the str type in Python 3, only text may be provided Expecter.expect() method.