thriftpy2

repository·master·Indexed 20 days ago

https://github.com/thriftpy/thriftpy2

A pure Python implementation of the Apache Thrift protocol that allows parsing Thrift IDL files and creating RPC clients and servers dynamically without requiring code generation or the official Apache Thrift compiler. It supports binary, compact, and JSON protocols, as well as buffered and framed transports. The library provides both synchronous and asyncio-compatible RPC servers and clients, and serves as a drop-in replacement for the deprecated thriftpy.

Tokens
9K
Snippets
35
Records
47
Agent score
64%

What's inside thriftpy2

  1. How ThriftPy2 works and its features

    master

    ThriftPy2 is a Pythonic implementation of Apache Thrift that is compatible with official Apache Thrift servers and clients.

    Key Features:

    • No Code Generation Required: Load .thrift files on the fly using thriftpy2.load() or an import hook.
    • Pure Python: No need to compile the official thrift package.
    • Compatibility: Works with official Apache Thrift implementations.
    • Supported Protocols & Transports:
      • Binary protocol (Python and Cython versions)
      • Compact protocol (Python and Cython versions)
      • JSON protocol
      • Buffered transport (Python and Cython versions)
      • Framed transport
    • Runtime Support: Python 3.6+ and PyPy3.
  2. Install ThriftPy2

    master

    Install ThriftPy2 using pip. For better performance, you can install cython first to allow ThriftPy2 to build Cython extensions locally, which enables accelerated binary and compact protocols.

    $ pip install thriftpy2
    
    # Recommended for performance (enables Cython extensions)
    $ pip install cython thriftpy2
  3. Override HTTP responses with `ResponseException`

    master

    In a THttpServer, handlers can raise a ResponseException to override the default behavior of always sending a 200 OK response.

    The ResponseException constructor takes a handler callable. This callable receives the RequestHandler (which is a subclass of http_server.BaseHTTPRequestHandler) as its only argument, allowing you to manually call methods like send_response, send_header, and end_headers to simulate different HTTP status codes or error scenarios.

  4. TAsyncClient internal request logic

    master

    The TAsyncClient manages the lifecycle of a Thrift request through several internal stages:

    1. Argument Mapping: Uses args_to_kwargs to map Python arguments to the Thrift service specification. If required arguments are missing, it raises a TApplicationException with TApplicationException.UNKNOWN_METHOD.
    2. Sending (_send): Determines if the method is oneway. It writes the message header (using TMessageType.ONEWAY or TMessageType.CALL), serializes the arguments, and flushes the transport.
    3. Receiving (_recv): Reads the response message. If the message type is TMessageType.EXCEPTION, it raises a TApplicationException.
    4. Result Processing:
      • For oneway methods, it returns immediately after sending.
      • For non-oneway methods, it extracts the success field from the result object.
      • If the method is void (empty thrift_spec), it returns None.
      • If the result contains an exception field, it raises that exception.
  5. Use TPayload for Thrift data structures

    master

    TPayload is the base class for all generated Thrift structs (payloads). It provides standard methods for serialization and comparison:

    • read(iprot): Reads the struct from the input protocol.
    • write(oprot): Writes the struct to the output protocol.
    • __eq__(other): Compares two payloads based on their field values.
    • __hash__(): Provides a hash consistent with __eq__, allowing structs to be used as keys in dictionaries or members of sets.
    • __repr__ / __str__: Provides a string representation of the struct fields.
  6. Create a Thrift RPC Client

    master

    To create a client, use thriftpy2.rpc.make_client. You must provide the service definition and the server's address and port.

    import thriftpy2
    from thriftpy2.rpc import make_client
    
    # 1. Load the thrift definition
    pingpong_thrift = thriftpy2.load("pingpong.thrift", module_name="pingpong_thrift")
    
    # 2. Connect to the server
    client = make_client(pingpong_thrift.PingPong, '127.0.0.1', 6000)
    
    # 3. Call methods
    print(client.ping())
  7. Create a synchronous RPC Server

    master

    To set up a synchronous RPC server, use thriftpy2.rpc.make_server. You must provide the service definition (from the loaded thrift module), an instance of a dispatcher class that implements the service methods, and the host/port.

    import thriftpy2
    from thriftpy2.rpc import make_server
    
    pingpong_thrift = thriftpy2.load("pingpong.thrift", module_name="pingpong_thrift")
    
    
    class Dispatcher(object):
        def ping(self):
            return "pong"
    
    
    server = make_server(pingpong_thrift.PingPong, Dispatcher(), '127.0.0.1', 6000)
    server.serve()
  8. Create an asyncio RPC Client

    master

    To use an asynchronous client, use thriftpy2.rpc.make_aio_client. This returns a coroutine that must be awaited to obtain the client instance. Remember to call client.close() when finished.

    import asyncio
    import thriftpy2
    from thriftpy2.rpc import make_aio_client
    
    pingpong_thrift = thriftpy2.load("pingpong.thrift", module_name="pingpong_thrift")
    
    
    async def main():
        client = await make_aio_client(pingpong_thrift.PingPong, '127.0.0.1', 6000)
        print(await client.ping())  # prints "pong"
        client.close()
    
    
    if __name__ == '__main__':
        asyncio.run(main())
  9. Create a synchronous RPC Client

    master

    To connect to a Thrift server, use thriftpy2.rpc.make_client. Pass the service definition, host, and port to create a client instance that mirrors the service interface.

    import thriftpy2
    from thriftpy2.rpc import make_client
    
    pingpong_thrift = thriftpy2.load("pingpong.thrift", module_name="pingpong_thrift")
    
    client = make_client(pingpong_thrift.PingPong, '127.0.0.1', 6000)
    print(client.ping())  # prints "pong"
  10. Create an asyncio RPC Server

    master

    For asynchronous support, use thriftpy2.rpc.make_aio_server. The dispatcher class methods must be defined as async def.

    import thriftpy2
    from thriftpy2.rpc import make_aio_server
    
    pingpong_thrift = thriftpy2.load("pingpong.thrift", module_name="pingpong_thrift")
    
    
    class Dispatcher(object):
        async def ping(self):
            return "pong"
    
    
    server = make_aio_server(pingpong_thrift.PingPong, Dispatcher(), '127.0.0.1', 6000)
    server.serve()