Twisted

Language: Python

Networking/CLI

Twisted was created by Glyph Lefkowitz in 2002 to simplify the development of networked applications in Python. It focuses on asynchronous I/O, making it suitable for high-performance network servers and clients. Twisted supports multiple protocols out-of-the-box and has a flexible architecture for custom protocol implementation.

Twisted is an event-driven networking engine written in Python. It provides a robust framework for building asynchronous networked applications, including servers, clients, and protocols for TCP, UDP, SSL/TLS, and more.

Installation

pip: pip install twisted
conda: conda install -c conda-forge twisted

Usage

Twisted uses an event-driven programming model where the reactor loop manages asynchronous events. Developers define protocols and factories to handle network events, such as connections, data received, and errors.

Simple TCP server

from twisted.internet import reactor, protocol

class Echo(protocol.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)

class EchoFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return Echo()

reactor.listenTCP(8000, EchoFactory())
reactor.run()

Creates a TCP server on port 8000 that echoes back any data received.

Simple TCP client

from twisted.internet import reactor, protocol

class EchoClient(protocol.Protocol):
    def connectionMade(self):
        self.transport.write(b'Hello, world!')
    def dataReceived(self, data):
        print('Server said:', data)
        self.transport.loseConnection()

class EchoFactory(protocol.ClientFactory):
    def buildProtocol(self, addr):
        return EchoClient()
    def clientConnectionFailed(self, connector, reason):
        print('Connection failed')
        reactor.stop()
    def clientConnectionLost(self, connector, reason):
        reactor.stop()

reactor.connectTCP('localhost', 8000, EchoFactory())
reactor.run()

Connects to a TCP server, sends a message, prints the response, and closes the connection.

Using Deferreds

from twisted.internet import reactor, defer

def got_result(result):
    print('Result:', result)
    reactor.stop()

d = defer.Deferred()
d.addCallback(got_result)
d.callback('Hello Twisted')
reactor.run()

Demonstrates the use of Deferred objects for handling asynchronous results and callbacks.

HTTP client request

from twisted.web.client import getPage
from twisted.internet import reactor

def print_result(result):
    print(result)
    reactor.stop()

getPage(b'http://httpbin.org/get').addCallback(print_result)
reactor.run()

Performs an asynchronous HTTP GET request and prints the page content.

Using SSL/TLS

from twisted.internet import ssl, reactor
from twisted.internet.protocol import Protocol, ClientFactory

class SecureClient(Protocol):
    def connectionMade(self):
        self.transport.write(b'Secure Hello')
    def dataReceived(self, data):
        print('Received:', data)
        self.transport.loseConnection()

class SecureFactory(ClientFactory):
    def buildProtocol(self, addr):
        return SecureClient()

reactor.connectSSL('localhost', 8000, SecureFactory(), ssl.ClientContextFactory())
reactor.run()

Shows how to establish a secure SSL/TLS client connection using Twisted.

Error Handling

ConnectionRefusedError: Ensure the server is running and reachable at the specified host and port.
twisted.internet.error.ReactorNotRunning: Check that reactor.run() has been called and not stopped prematurely.
TimeoutError: Use Twisted’s timeout mechanisms or Deferred timeouts to handle slow connections.

Best Practices

Use the reactor loop for all asynchronous operations.

Leverage Deferreds for handling asynchronous callbacks and chaining operations.

Use Factories to manage protocol instances and connections.

Avoid blocking calls inside Twisted protocols; use threads or deferToThread for blocking operations.

Use Twisted’s built-in protocols and utilities to simplify network programming.