Install & Compatibility
Where this runs
tested against v0.24.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.044s · 23.3MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.0s · import 0.036s · 20MB
19MB installed
● package 19MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
TSocket
✓ from thrift.transport import TSocket
TBufferedTransport
✓ from thrift.transport import TBufferedTransport
TBinaryProtocol
✓ from thrift.protocol import TBinaryProtocol
TSimpleServer
✓ from thrift.server import TServer
✗ from thrift.server import TSimpleServer
TSimpleServer, TThreadPoolServer, etc., are attributes of the TServer module, not direct imports in many examples. The correct import is usually 'from thrift.server import TServer', then access TServer.TSimpleServer().
TException
✓ from thrift import Thrift; Thrift.TException
To use Apache Thrift in Python, you first define your service in a `.thrift` IDL file. Then, you use the Apache Thrift compiler (a C++ executable, not `pip install thrift`) to generate Python client and server stubs from this IDL. The generated code lives in a `gen-py` directory. The example demonstrates a simple `Calculator` service with `add` and `ping` methods, showing basic server and client setup.
# 1. Define your service in 'calculator.thrift'
# namespace py tutorial
# service Calculator {
# i32 add(1:i32 num1, 2:i32 num2),
# void ping()
# }
# 2. Generate Python code using the Thrift compiler:
# thrift --gen py calculator.thrift
# This creates a 'gen-py' directory with 'tutorial' module.
import sys
import os
import time
# Ensure 'gen-py' is on the path to import generated code
current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(current_dir, 'gen-py'))
# Generated code imports
from tutorial import Calculator
from tutorial.ttypes import *
# Thrift core library imports
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
# --- Server Implementation ---
class CalculatorHandler:
def __init__(self):
self.log = {}
def ping(self):
print('Server: ping()')
def add(self, num1, num2):
print(f'Server: add({num1}, {num2})')
return num1 + num2
def start_server():
handler = CalculatorHandler()
processor = Calculator.Processor(handler)
transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print('Starting the server on port 9090...')
# In a real application, you might run this in a separate process or thread
# For this quickstart, we'll simulate a long-running server
# server.serve() # This blocks
return server # Return server for demonstration, typically would call serve()
# --- Client Implementation ---
def run_client():
# Make socket
transport = TSocket.TSocket('localhost', 9090)
# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)
# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = Calculator.Client(protocol)
# Connect!
try:
transport.open()
print('Client: Connected to server.')
client.ping()
print('Client: ping() sent.')
sum_result = client.add(5, 7)
print(f'Client: 5 + 7 = {sum_result}')
except TException as tx:
print(f'Client: Error: {tx.message}')
finally:
transport.close()
print('Client: Connection closed.')
if __name__ == '__main__':
# This part demonstrates server setup and a client call in sequence.
# For actual usage, server and client would typically run in separate processes.
server_instance = start_server()
# In a real scenario, you would start the server in a background thread or process.
# For simplicity, we'll run the client immediately assuming the server is ready.
# You might need a small delay for the server to fully start in a real async scenario.
print("Quickstart: Server started (not blocking), running client now...")
run_client()
print("Quickstart: Client finished. If server was blocking, it would still be running.")
# If server_instance.serve() was called, you'd need a way to stop it.
thrift --version
Debug
Known issues
breakingApache Thrift 0.22.0 introduced significant breaking changes for some language bindings (e.g., .NET Standard namespace and class name changes like `TServerSocket` to `TServerSocketTransport`, `TSimpleServer` to `TSimpleAsyncServer`). While the core Python API hasn't seen as many direct breaking changes in naming within the `thrift` package itself for this version, applications might still need adjustments, especially if depending on specific compiler flag behaviors or generated code specifics that were updated. Always re-generate Python code with the latest compiler for consistency.fixRe-generate Python code from `.thrift` files using the `thrift` compiler version 0.22.0 or newer. Review generated code and update client/server implementations to match any altered patterns or class names in the generated stubs or core library.
affects: 0.22.0 and later
gotchaThe `pip install thrift` package provides only the Python runtime libraries. It DOES NOT include the `thrift` compiler (a C++ executable) which is absolutely necessary to generate Python client/server stub code from your `.thrift` IDL files. This compiler must be installed separately (e.g., via a package manager like `apt`, `brew`, or by building from source).fixInstall the Apache Thrift compiler executable (`thrift`) separately from the Python library. Consult the official Apache Thrift documentation for instructions on installing the compiler for your operating system.
affects: All versions
gotchaDo not confuse the official `thrift` library (which requires code generation) with `thriftpy` or `thriftpy2`. `thriftpy`/`thriftpy2` are alternative, pure Python implementations that can dynamically load `.thrift` files at runtime without a separate compiler step. Attempting to use `thriftpy`'s dynamic loading or API (`thriftpy.load()`) with the official `thrift` library will lead to `AttributeError` or `ImportError`.fixChoose one implementation (`thrift` or `thriftpy`/`thriftpy2`) and stick to its API and workflow. If using the official `thrift`, always use the `thrift --gen py` command to generate code before importing.
affects: All versions
gotchaWhen importing generated Thrift code, examples often use `sys.path.append('gen-py')` to make the generated modules discoverable. While functional for quickstarts, this is not a best practice for production environments as it bypasses standard Python packaging mechanisms and can lead to module resolution issues.fixFor production, consider installing the generated Python code as a proper Python package (e.g., using `setuptools` and defining the generated directory as a package) or ensuring it's part of your application's installable modules that are correctly added to `PYTHONPATH`.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'your_service_name.ttypes'
The Python interpreter cannot find the modules generated by the `thrift` compiler because the directory containing them (e.g., `gen-py`) is not in `sys.path`.
fixAdd the directory containing the generated Python modules to `sys.path` at runtime or ensure it's part of your `PYTHONPATH` environment variable before importing. Example: `import sys; sys.path.append('./gen-py'); from your_service_name.ttypes import MyStruct` sh: thrift: command not found
The Apache Thrift compiler executable is not installed on the system or is not present in the system's PATH environment variable.
fixInstall the Apache Thrift compiler using your system's package manager (e.g., `sudo apt-get install thrift-compiler` on Debian/Ubuntu, `brew install thrift` on macOS) or by building it from source.
thrift.transport.TTransportException: Could not connect to host localhost:9090
The Thrift client failed to establish a connection with the Thrift server, typically because the server is not running, is listening on a different host/port, or a firewall is blocking the connection.
fixEnsure the Thrift server is running and listening on the specified host and port, and verify network connectivity and firewall rules.
thrift.protocol.TProtocolException: Bad version in readMessageBegin
The Thrift client and server are configured to use different protocol implementations, leading to a mismatch in how messages are serialized and deserialized.
fixEnsure both the Thrift client and server are configured to use the exact same protocol factory (e.g., both use `TBinaryProtocol.TBinaryProtocolFactory` or both use `TCompactProtocol.TCompactProtocolFactory`).
Upgrade
Version history
0.24.0latest on PyPI · released Jul 11, 2026
Audit
Dependencies
python-tornadooptionalOptional backend for Tornado-based servers/clients.
python-twistedoptionalOptional backend for Twisted-based servers/clients.
Apache Thrift Compiler (C++ executable)requiredRequired to generate Python code from .thrift IDL files.