{"id":2312,"library":"thriftpy2","title":"ThriftPy2","description":"ThriftPy2 is a pure Python implementation of the Apache Thrift protocol, version 0.6.0. It allows developers to parse Thrift IDL files and create RPC clients/servers dynamically without code generation or compilation. The library maintains an active development status with regular updates, including recent beta releases leading to stable versions.","status":"active","version":"0.6.0","language":"en","source_language":"en","source_url":"https://github.com/Thriftpy/thriftpy2","tags":["thrift","rpc","protocol","apache thrift","idl","asyncio"],"install":[{"cmd":"pip install thriftpy2","lang":"bash","label":"Install stable version"},{"cmd":"pip install cython thriftpy2","lang":"bash","label":"Install with Cython for performance"}],"dependencies":[{"reason":"Required for parsing Thrift IDL files.","package":"ply","optional":false},{"reason":"Provides backported and experimental type hints.","package":"typing-extensions","optional":false},{"reason":"Optional for improved performance of binary and compact protocols.","package":"cython","optional":true}],"imports":[{"note":"Main library import for dynamic IDL loading and core functionalities.","symbol":"thriftpy2","correct":"import thriftpy2"},{"note":"Used to create synchronous Thrift RPC servers.","symbol":"make_server","correct":"from thriftpy2.rpc import make_server"},{"note":"Used to create asynchronous Thrift RPC clients with asyncio.","symbol":"make_aio_client","correct":"from thriftpy2.rpc import make_aio_client"},{"note":"The original 'thriftpy' library is deprecated. For compatibility, migrate to 'thriftpy2' and import it with an alias if needed.","wrong":"import thriftpy","symbol":"thriftpy","correct":"import thriftpy2 as thriftpy"}],"quickstart":{"code":"import asyncio\nimport thriftpy2\nfrom thriftpy2.rpc import make_aio_client\nimport os\n\n# Define a simple Thrift service IDL in a temporary file\nTHRIFT_FILE_PATH = \"pingpong.thrift\"\nwith open(THRIFT_FILE_PATH, \"w\") as f:\n    f.write(\"service PingPong {\\n    string ping(),\\n}\")\n\n# Load the thrift file dynamically\npingpong_thrift = thriftpy2.load(THRIFT_FILE_PATH, module_name=\"pingpong_thrift\")\n\nasync def main():\n    print(\"Attempting to create ThriftPy2 async client...\")\n    client = None\n    try:\n        # For this quickstart, we'll demonstrate client instantiation and a call pattern.\n        # Note: This client will attempt to connect to '127.0.0.1:6000'.\n        # A running ThriftPy2 server on this address would be required for a successful RPC call.\n        # This example focuses on demonstrating the client API, not a full RPC pair.\n        client = await make_aio_client(\n            pingpong_thrift.PingPong,\n            '127.0.0.1',\n            6000,\n            timeout=1000 # Milliseconds for connection/read timeout\n        )\n        print(\"Client created. Attempting to call ping()... (This will likely fail without a running server)\")\n        # Example of calling a service method\n        # result = await client.ping()\n        # print(f\"Ping result: {result}\")\n\n    except Exception as e:\n        print(f\"Error setting up client (expected if no server is running at 127.0.0.1:6000): {e}\")\n    finally:\n        if client:\n            client.close()\n        # Clean up the dummy thrift file\n        if os.path.exists(THRIFT_FILE_PATH):\n            os.remove(THRIFT_FILE_PATH)\n\nif __name__ == '__main__':\n    asyncio.run(main())\n","lang":"python","description":"This quickstart demonstrates how to dynamically load a Thrift IDL file and instantiate an asynchronous client using `thriftpy2.rpc.make_aio_client`. It creates a temporary `pingpong.thrift` file, loads it, and attempts to connect to a local server. Note that for a successful RPC call, a ThriftPy2 server must be running at the specified address and port."},"warnings":[{"fix":"Migrate your server and client implementations to use `asyncio` (e.g., `make_aio_server`, `make_aio_client`) or other supported HTTP transports available in `thriftpy2`.","message":"Support for Tornado-based servers and clients has been deprecated in v0.6.0. Users relying on `thriftpy2.tornado` modules should migrate to `asyncio` or other HTTP transports.","severity":"deprecated","affected_versions":">=0.6.0"},{"fix":"For full compatibility, change `import thriftpy` to `import thriftpy2 as thriftpy`. This ensures your code continues to reference the library under the original name while using `thriftpy2`'s implementation.","message":"When migrating from the original `thriftpy` library, simply changing import statements from `import thriftpy` to `import thriftpy2` might cause issues if other parts of your code still expect the `thriftpy` namespace. While `thriftpy2` is designed for compatibility, direct renaming is safer.","severity":"gotcha","affected_versions":"all"},{"fix":"When installing `thriftpy2` in a CPython environment, explicitly install `cython` first (`pip install cython thriftpy2`) or use `pip install --no-binary thriftpy2 thriftpy2` to force a source build. Alternatively, clear your `pip` cache if you've previously installed in PyPy.","message":"If you install `thriftpy2` in a PyPy virtual environment, `pip` might generate a universal wheel without Cython extensions. Using this cached wheel later in a CPython environment can lead to `ModuleNotFoundError: No module named 'thriftpy2.protocol.cybin'` because CPython expects the Cython-compiled modules.","severity":"gotcha","affected_versions":"all"},{"fix":"Always provide a `module_name` argument when calling `thriftpy2.load()`, e.g., `my_thrift = thriftpy2.load('my.thrift', module_name='my_thrift_module')`. This ensures the generated objects are pickleable.","message":"When dynamically loading Thrift IDL files using `thriftpy2.load()`, if you do not provide the `module_name` argument, the generated Thrift objects cannot be pickled. This can cause issues with serialization in distributed systems or caching.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}