PySerial
PySerialDocs

API Reference

Complete PySerial API reference. All methods, properties, constants, and exceptions for the serial.Serial class and port discovery utilities.

Reference for serial.Serial, port discovery, constants, and exceptions.

serial.Serial Constructor

serial.Serial(
    port=None,
    baudrate=9600,
    bytesize=EIGHTBITS,
    parity=PARITY_NONE,
    stopbits=STOPBITS_ONE,
    timeout=None,
    xonxoff=False,
    rtscts=False,
    write_timeout=None,
    dsrdtr=False,
    inter_byte_timeout=None,
    exclusive=None,
)
ParameterTypeDefaultDescription
portstr or NoneNoneDevice name (/dev/ttyUSB0, COM3). If None, port must be opened later with open().
baudrateint9600Bits per second
bytesizeintEIGHTBITS (8)Data bits: 5, 6, 7, or 8
paritystrPARITY_NONE ('N')'N', 'E', 'O', 'M', or 'S'
stopbitsfloatSTOPBITS_ONE (1)1, 1.5, or 2
timeoutfloat or NoneNoneRead timeout (seconds). None = block, 0 = non-blocking
xonxoffboolFalseSoftware flow control
rtsctsboolFalseHardware RTS/CTS flow control
write_timeoutfloat or NoneNoneWrite timeout (seconds)
dsrdtrboolFalseDSR/DTR flow control
inter_byte_timeoutfloat or NoneNoneInter-byte read timeout
exclusivebool or NoneNoneExclusive access (Linux only)
import serial

# Minimal
ser = serial.Serial('/dev/ttyUSB0', 9600)

# Full configuration
ser = serial.Serial('/dev/ttyUSB0', 115200,
    bytesize=8, parity='N', stopbits=1,
    timeout=1, write_timeout=1, rtscts=True)

# Create without opening
ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 9600
ser.open()

Log serial data automatically

TofuPilot records test results from your PySerial scripts, tracks pass/fail rates, and generates compliance reports. Free to start.

Properties

Port Information

PropertyTypeRead/WriteDescription
portstrR/WPort name or device path
namestrRDevice name (same as port)
is_openboolRTrue if port is currently open

Communication Settings

PropertyTypeRead/WriteDescription
baudrateintR/WBaud rate
bytesizeintR/WData bits (5-8)
paritystrR/WParity setting
stopbitsfloatR/WStop bits
timeoutfloat or NoneR/WRead timeout (seconds)
write_timeoutfloat or NoneR/WWrite timeout (seconds)
inter_byte_timeoutfloat or NoneR/WInter-byte timeout

Flow Control

PropertyTypeRead/WriteDescription
xonxoffboolR/WSoftware flow control enabled
rtsctsboolR/WHardware RTS/CTS flow control enabled
dsrdtrboolR/WDSR/DTR flow control enabled

Buffer Status

PropertyTypeRead/WriteDescription
in_waitingintRBytes in the input buffer
out_waitingintRBytes in the output buffer (platform-dependent)

Modem Control Lines

PropertyTypeRead/WriteDescription
dtrboolR/WData Terminal Ready
rtsboolR/WRequest To Send
ctsboolRClear To Send
dsrboolRData Set Ready
riboolRRing Indicator
cdboolRCarrier Detect
import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

print(f"Port: {ser.port}")
print(f"Open: {ser.is_open}")
print(f"Baud: {ser.baudrate}")
print(f"Input buffer: {ser.in_waiting} bytes")
print(f"CTS: {ser.cts}, DSR: {ser.dsr}")

# Change settings on the fly
ser.baudrate = 115200
ser.timeout = 2.0

ser.close()

Read Methods

read(size=1)

Read up to size bytes. Returns fewer bytes if timeout expires before size bytes arrive.

Parameters:

NameTypeDefaultDescription
sizeint1Maximum bytes to read

Returns: bytes (length 0 to size)

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=2)

# Read exactly 1 byte
byte = ser.read()

# Read up to 10 bytes
data = ser.read(10)
if len(data) < 10:
    print(f"Timeout: got {len(data)} of 10 bytes")

ser.close()

readline(size=-1)

Read bytes until \n is found or size bytes have been read. Requires a timeout to avoid blocking forever if no newline arrives.

Parameters:

NameTypeDefaultDescription
sizeint-1Max bytes to read. -1 for no limit.

Returns: bytes (includes the \n terminator if found)

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

line = ser.readline()
text = line.decode('utf-8').strip()
print(text)

# With size limit
line = ser.readline(100)

ser.close()

read_until(expected=b'\n', size=None)

Read bytes until expected sequence is found or size bytes have been read.

Parameters:

NameTypeDefaultDescription
expectedbytesb'\n'Terminator sequence to search for
sizeint or NoneNoneMax bytes to read. None for no limit.

Returns: bytes (includes the expected terminator if found)

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=2)

# Read until "OK" response
response = ser.read_until(b'OK')

# Read until custom packet delimiter
packet = ser.read_until(b'</packet>')

# With size limit
data = ser.read_until(b'END', size=1000)

ser.close()

read_all()

Read all bytes currently in the input buffer. Equivalent to ser.read(ser.in_waiting).

Returns: bytes

import serial
import time

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

time.sleep(0.5)  # let data accumulate
if ser.in_waiting:
    data = ser.read_all()
    print(f"Got {len(data)} bytes")

ser.close()

Write Methods

write(data)

Write bytes to the serial port.

Parameters:

NameTypeDescription
databytes or bytearrayData to transmit

Returns: int (number of bytes written)

Raises: SerialTimeoutException if write_timeout is set and expires

import serial
import struct

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

# Write raw bytes
ser.write(b'Hello\n')

# Write encoded string
ser.write("AT+GMR\r\n".encode('utf-8'))

# Write binary struct
data = struct.pack('>HHf', 1234, 5678, 25.6)
ser.write(data)

ser.close()

writelines(lines)

Write an iterable of byte strings. Does not add separators between items.

Parameters:

NameTypeDescription
linesiterable of bytesSequence of byte strings
import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

commands = [b'AT\r\n', b'ATE0\r\n', b'AT+GMR\r\n']
ser.writelines(commands)

ser.close()

flush()

Block until all data in the output buffer has been transmitted.

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

ser.write(b'COMMAND\r\n')
ser.flush()  # wait until bytes are on the wire
response = ser.readline()

ser.close()

Control Methods

open()

Open the serial port. Called automatically by the constructor when port is provided.

Raises: SerialException if the port cannot be opened.

import serial

ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 9600

ser.open()
print(f"Opened: {ser.is_open}")
ser.close()

close()

Close the serial port and release the resource.

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600)
# ... do work ...
ser.close()

reset_input_buffer()

Clear the receive buffer, discarding all unread data.

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

# Discard stale data before sending a command
ser.reset_input_buffer()
ser.write(b'AT\r\n')
response = ser.readline()

ser.close()

reset_output_buffer()

Clear the transmit buffer, discarding all unsent data.

send_break(duration=0.25)

Send a break condition for duration seconds.

Parameters:

NameTypeDefaultDescription
durationfloat0.25Break duration in seconds
import serial

ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.send_break(0.5)
ser.close()

set_buffer_size(rx_size=4096, tx_size=None)

Set internal buffer sizes. Platform-dependent; may raise AttributeError if not supported.

Parameters:

NameTypeDefaultDescription
rx_sizeint4096Receive buffer size in bytes
tx_sizeint or NoneNoneTransmit buffer size in bytes

Port Discovery

serial.tools.list_ports.comports(include_links=False)

List all available serial ports on the system.

Parameters:

NameTypeDefaultDescription
include_linksboolFalseInclude symlinks (Linux/macOS)

Returns: List of ListPortInfo objects

import serial.tools.list_ports

for port in serial.tools.list_ports.comports():
    print(f"{port.device}: {port.description}")
    if port.vid:
        print(f"  USB VID:PID = {port.vid:04X}:{port.pid:04X}")

ListPortInfo Properties

PropertyTypeDescription
devicestrDevice path (/dev/ttyUSB0, COM3)
namestrShort device name
descriptionstrHuman-readable description
hwidstrHardware ID string
vidint or NoneUSB Vendor ID
pidint or NoneUSB Product ID
serial_numberstr or NoneUSB serial number
locationstr or NonePhysical USB location
manufacturerstr or NoneManufacturer name
productstr or NoneProduct name
interfacestr or NoneInterface description

URL Handlers

PySerial supports URL-style port specifications for special backends.

SchemeDescriptionExample
socket://TCP/IP socketsocket://192.168.1.100:7777
rfc2217://Remote serial over networkrfc2217://server:4000
loop://Loopback (testing)loop://
hwgrep://Hardware grephwgrep://0403:6001
import serial

# Loopback for testing (no hardware needed)
ser = serial.Serial('loop://', timeout=1)
ser.write(b'test')
print(ser.read(4))  # b'test'
ser.close()

# TCP socket to a serial-over-IP device
ser = serial.Serial('socket://192.168.1.100:7777', timeout=1)

# Find FTDI device by USB IDs
ser = serial.Serial('hwgrep://0403:6001')

Constants

Byte Size

ConstantValue
serial.FIVEBITS5
serial.SIXBITS6
serial.SEVENBITS7
serial.EIGHTBITS8

Parity

ConstantValue
serial.PARITY_NONE'N'
serial.PARITY_EVEN'E'
serial.PARITY_ODD'O'
serial.PARITY_MARK'M'
serial.PARITY_SPACE'S'

Stop Bits

ConstantValue
serial.STOPBITS_ONE1
serial.STOPBITS_ONE_POINT_FIVE1.5
serial.STOPBITS_TWO2

Exceptions

ExceptionParentRaised When
serial.SerialExceptionExceptionPort doesn't exist, permission denied, device disconnected
serial.SerialTimeoutExceptionSerialExceptionRead or write timeout exceeded
serial.PortNotOpenErrorSerialExceptionOperation on a closed port
serial.WriteTimeoutErrorSerialTimeoutExceptionWrite timeout exceeded
import serial

try:
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.write(b'test')
    data = ser.read(10)
except serial.SerialTimeoutException:
    print("Operation timed out")
except serial.SerialException as e:
    print(f"Serial error: {e}")
except PermissionError:
    print("Permission denied")
except FileNotFoundError:
    print("Port not found")
finally:
    if 'ser' in locals() and ser.is_open:
        ser.close()

Context Manager

serial.Serial supports with for automatic cleanup.

import serial

with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser:
    ser.write(b'data\n')
    response = ser.read(100)
# port is closed automatically

Version

import serial

print(serial.__version__)  # e.g., '3.5'