Python selectors Module

🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.

▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube

▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube

The selectors module in Python provides a high-level I/O multiplexing interface built on top of the lower-level select module primitives (select, poll, epoll, and kqueue). This module allows you to manage multiple I/O events in a more efficient and portable way.

Table of Contents

  1. Introduction
  2. Key Classes and Methods
    • DefaultSelector
    • EVENT_READ
    • EVENT_WRITE
    • register
    • unregister
    • select
  3. Examples
    • Basic Usage of selectors
    • Creating a Simple Server
    • Handling Multiple Connections
    • Real-World Use Case: Chat Server
  4. Conclusion
  5. References

Introduction

The selectors module provides a unified interface for monitoring multiple I/O events, making it easier to write portable and efficient I/O code. It abstracts the platform-specific details and allows you to work with a common interface for handling I/O readiness.

Key Classes and Methods

DefaultSelector

Creates a default selector object which automatically selects the most efficient implementation available on the platform (epoll on Linux, kqueue on BSD, select on Windows, etc.).

import selectors

sel = selectors.DefaultSelector()

EVENT_READ

Constant to indicate that the file object is ready for reading.

selectors.EVENT_READ

EVENT_WRITE

Constant to indicate that the file object is ready for writing.

selectors.EVENT_WRITE

register

Registers a file object for monitoring.

sel.register(fileobj, selectors.EVENT_READ | selectors.EVENT_WRITE, data)

unregister

Unregisters a file object from monitoring.

sel.unregister(fileobj)

select

Monitors registered file objects and returns a list of ready file objects.

events = sel.select(timeout)

Examples

Basic Usage of selectors

import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock):
    conn, addr = sock.accept()
    print(f'Accepted connection from {addr}')
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn):
    data = conn.recv(1024)
    if data:
        print(f'Received data: {data}')
        conn.send(data)  # Echo back the data
    else:
        print('Closing connection')
        sel.unregister(conn)
        conn.close()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 12345))
sock.listen()
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj)

Creating a Simple Server

import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()
    print(f'Accepted connection from {addr}')
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn, mask):
    data = conn.recv(1024)
    if data:
        print(f'Received data: {data}')
        conn.send(data)
    else:
        print('Closing connection')
        sel.unregister(conn)
        conn.close()

sock = socket.socket()
sock.bind(('localhost', 12345))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)

Handling Multiple Connections

import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()
    print(f'Accepted connection from {addr}')
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn, mask):
    data = conn.recv(1024)
    if data:
        print(f'Received data: {data}')
        conn.send(data)
    else:
        print('Closing connection')
        sel.unregister(conn)
        conn.close()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 12345))
sock.listen()
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)

Real-World Use Case: Chat Server

import selectors
import socket

sel = selectors.DefaultSelector()
clients = {}

def accept(sock, mask):
    conn, addr = sock.accept()
    print(f'Accepted connection from {addr}')
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)
    clients[conn] = addr

def read(conn, mask):
    data = conn.recv(1024)
    if data:
        print(f'Received data from {clients[conn]}: {data.decode()}')
        broadcast(data, conn)
    else:
        print(f'Closing connection to {clients[conn]}')
        sel.unregister(conn)
        conn.close()
        del clients[conn]

def broadcast(message, sender):
    for conn in clients:
        if conn != sender:
            conn.send(message)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 12345))
sock.listen()
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

print('Chat server started on port 12345')

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)

Conclusion

The selectors module in Python provides a high-level interface for efficient I/O multiplexing, making it easier to write portable and efficient network code. By abstracting the platform-specific details, it allows you to focus on building your application without worrying about the underlying system calls.

References

My Top and Bestseller Udemy Courses. The sale is going on with a 70 - 80% discount. The discount coupon has been added to each course below:

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare