From cde2b61c5e3a26fd6ad5bc1a6fcdee449696d66c Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Sun, 3 Sep 2006 21:13:07 +0000 Subject: [PATCH] Implementation of the basic Thrift stack in Python Summary: Framework, install script, base classes, TSocket, TBinaryProtocol Notes: Code-gen is coming around the bend... git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664778 13f79535-47bb-0310-9956-ffa450edef68 --- lib/py/setup.py | 12 ++ lib/py/src/Thrift.py | 0 lib/py/src/__init__.py | 1 + lib/py/src/protocol/TBinaryProtocol.py | 159 ++++++++++++++++++++++ lib/py/src/protocol/TProtocol.py | 180 +++++++++++++++++++++++++ lib/py/src/protocol/__init__.py | 1 + lib/py/src/transport/TSocket.py | 45 +++++++ lib/py/src/transport/TTransport.py | 25 ++++ lib/py/src/transport/__init__.py | 1 + 9 files changed, 424 insertions(+) create mode 100644 lib/py/setup.py create mode 100644 lib/py/src/Thrift.py create mode 100644 lib/py/src/__init__.py create mode 100644 lib/py/src/protocol/TBinaryProtocol.py create mode 100644 lib/py/src/protocol/TProtocol.py create mode 100644 lib/py/src/protocol/__init__.py create mode 100644 lib/py/src/transport/TSocket.py create mode 100644 lib/py/src/transport/TTransport.py create mode 100644 lib/py/src/transport/__init__.py diff --git a/lib/py/setup.py b/lib/py/setup.py new file mode 100644 index 00000000..4beaba7c --- /dev/null +++ b/lib/py/setup.py @@ -0,0 +1,12 @@ +from distutils.core import setup + +setup(name = 'Thrift', + version = '1.0', + description = 'Thrift Python Libraries', + author = ['Mark Slee'], + author_email = ['mcslee@facebook.com'], + url = 'http://code.facebook.com/thrift', + packages = ['thrift', 'thrift.protocol', 'thrift.transport'] + package_dir = {'thrift' : 'src'}, + ) + diff --git a/lib/py/src/Thrift.py b/lib/py/src/Thrift.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/py/src/__init__.py b/lib/py/src/__init__.py new file mode 100644 index 00000000..9ddc3ce1 --- /dev/null +++ b/lib/py/src/__init__.py @@ -0,0 +1 @@ +__all__ = ["Thrift"] diff --git a/lib/py/src/protocol/TBinaryProtocol.py b/lib/py/src/protocol/TBinaryProtocol.py new file mode 100644 index 00000000..c089ac57 --- /dev/null +++ b/lib/py/src/protocol/TBinaryProtocol.py @@ -0,0 +1,159 @@ +from TProtocol import * +from struct import pack, unpack + +class TBinaryProtocol(TProtocolBase): + + """Binary implementation of the Thrift protocol driver.""" + + def writeMessageBegin(self, otrans, name, type, seqid): + self.writeString(otrans, name) + self.writeByte(otrans, type) + self.writeI32(otrans, seqid) + + def writeMessageEnd(self, otrans): + pass + + def writeStructBegin(self, otrans, name): + pass + + def writeStructEnd(self, otrans): + pass + + def writeFieldBegin(self, otrans, name, type, id): + self.writeByte(otrans, type) + self.writeI16(otrans, id) + + def writeFieldEnd(self, otrans): + pass + + def writeFieldStop(self, otrans): + self.writeByte(otrans, TType.STOP); + + def writeMapBegin(self, otrans, ktype, vtype, size): + self.writeByte(otrans, ktype) + self.writeByte(otrans, vtype) + self.writeI32(otrans, size) + + def writeMapEnd(self, otrans): + pass + + def writeListBegin(self, otrans, etype, size): + self.writeByte(otrans, etype) + self.writeI32(otrans, size) + + def writeListEnd(self, otrans): + pass + + def writeSetBegin(self, otrans, etype, size): + self.writeByte(otrans, etype) + self.writeI32(otrans, size) + + def writeSetEnd(self, otrans): + pass + + def writeBool(self, otrans, bool): + if bool: + self.writeByte(otrans, 1) + else: + self.writeByte(otrans, 0) + + def writeByte(self, otrans, byte): + buff = pack("!b", byte) + otrans.write(buff) + + def writeI16(self, otrans, i16): + buff = pack("!h", i16) + otrans.write(buff) + + def writeI32(self, otrans, i32): + buff = pack("!i", i32) + otrans.write(buff) + + def writeI64(self, otrans, i64): + buff = pack("!l", i64) + otrans.write(buff) + + def writeString(self, otrans, str): + self.writeI32(otrans, len(str)) + otrans.write(str) + + def readMessageBegin(self, itrans): + name = self.readString(itrans) + type = self.readByte(itrans) + seqid = self.readI32(itrans) + return (name, type, seqid) + + def readMessageEnd(self, itrans): + pass + + def readStructBegin(self, itrans): + pass + + def readStructEnd(self, itrans): + pass + + def readFieldBegin(self, itrans): + type = self.readByte(itrans) + if type == TType.STOP: + return (None, type, 0) + id = self.readI16(itrans) + return (None, type, id) + + def readFieldEnd(self, itrans): + pass + + def readMapBegin(self, itrans): + ktype = self.readByte(itrans) + vtype = self.readByte(itrans) + size = self.readI32(itrans) + return (ktype, vtype, size) + + def readMapEnd(self, itrans): + pass + + def readListBegin(self, itrans): + etype = self.readByte(itrans) + size = self.readI32(itrans) + return (etype, size) + + def readListEnd(self, itrans): + pass + + def readSetBegin(self, itrans): + etype = self.readByte(itrans) + size = self.readI32(itrans) + return (etype, size) + + def readSetEnd(self, itrans): + pass + + def readBool(self, itrans): + byte = self.readByte(itrans) + if byte == 0: + return False + return True + + def readByte(self, itrans): + buff = itrans.readAll(1) + val, = unpack('!b', buff) + return val + + def readI16(self, itrans): + buff = itrans.readAll(2) + val, = unpack('!h', buff) + return val + + def readI32(self, itrans): + buff = itrans.readAll(4) + val, = unpack('!i', buff) + return val + + def readI64(self, itrans): + buff = itrans.readAll(8) + val, = unpack('!l', buff) + return val + + def readString(self, itrans): + len = self.readI32(itrans) + str = itrans.readAll(len) + return str diff --git a/lib/py/src/protocol/TProtocol.py b/lib/py/src/protocol/TProtocol.py new file mode 100644 index 00000000..3105e254 --- /dev/null +++ b/lib/py/src/protocol/TProtocol.py @@ -0,0 +1,180 @@ +class TType: + STOP = 0 + VOID = 1 + BOOL = 2 + BYTE = 3 + I08 = 4 + I16 = 6 + I32 = 8 + I64 = 10 + STRING = 11 + UTF7 = 11 + STRUCT = 12 + MAP = 13 + SET = 14 + LIST = 15 + UTF8 = 16 + UTF16 = 17 + +class TMessageType: + CALL = 1 + REPLY = 2 + +class TProtocolBase: + + """Base class for Thrift protocol driver.""" + + def writeMessageBegin(self, otrans, name, type, seqid): + pass + + def writeMessageEnd(self, otrans): + pass + + def writeStructBegin(self, otrans, name): + pass + + def writeStructEnd(self, otrans): + pass + + def writeFieldBegin(self, otrans, name, type, id): + pass + + def writeFieldEnd(self, otrans): + pass + + def writeFieldStop(self, otrans): + pass + + def writeMapBegin(self, otrans, ktype, vtype, size): + pass + + def writeMapEnd(self, otrans): + pass + + def writeListBegin(self, otrans, etype, size): + pass + + def writeListEnd(self, otrans): + pass + + def writeSetBegin(self, otrans, etype, size): + pass + + def writeSetEnd(self, otrans): + pass + + def writeBool(self, otrans, bool): + pass + + def writeByte(self, otrans, byte): + pass + + def writeI16(self, otrans, i16): + pass + + def writeI32(self, otrans, i32): + pass + + def writeI64(self, otrans, i64): + pass + + def writeString(self, otrans, str): + pass + + def readMessageBegin(self, itrans): + pass + + def readMessageEnd(self, itrans): + pass + + def readStructBegin(self, itrans): + pass + + def readStructEnd(self, itrans): + pass + + def readFieldBegin(self, itrans): + pass + + def readFieldEnd(self, itrans): + pass + + def readMapBegin(self, itrans): + pass + + def readMapEnd(self, itrans): + pass + + def readListBegin(self, itrans): + pass + + def readListEnd(self, itrans): + pass + + def readSetBegin(self, itrans): + pass + + def readSetEnd(self, itrans): + pass + + def readBool(self, itrans): + pass + + def readByte(self, itrans): + pass + + def readI16(self, itrans): + pass + + def readI32(self, itrans): + pass + + def readI64(self, itrans): + pass + + def readString(self, itrans): + pass + + def skip(self, itrans, type): + if type == TType.STOP: + return + elif type == TType.BOOL: + self.readBool(itrans) + elif type == TType.BYTE: + self.readByte(itrans) + elif type == TType.I16: + self.readI16(itrans) + elif type == TType.I32: + self.readI32(itrans) + elif type == TType.I64: + self.readI64(itrans) + elif type == TType.STRING: + self.readString(itrans) + elif type == TType.STRUCT: + name = self.readStructBegin(itrans) + while True: + (name, type, id) = self.readFieldBegin(itrans) + if type == TType.STOP: + break + self.skip(itrans, type) + self.readFieldEnd(itrans) + self.readStructEnd(itrans) + elif type == TType.MAP: + (ktype, vtype, size) = self.readMapBegin(itrans) + for i in range(size): + self.skip(itrans, ktype) + self.skip(itrans, vtype) + self.readMapEnd(itrans) + elif type == TType.SET: + (etype, size) = self.readSetBegin(itrans) + for i in range(size): + self.skip(itrans, etype) + self.readSetEnd(itrans) + elif type == TType.LIST: + (etype, size) = self.readListBegin(itrans) + for i in range(size): + self.skip(itrans, etype) + self.readListEnd(itrans) + + + diff --git a/lib/py/src/protocol/__init__.py b/lib/py/src/protocol/__init__.py new file mode 100644 index 00000000..e0c1c5e5 --- /dev/null +++ b/lib/py/src/protocol/__init__.py @@ -0,0 +1 @@ +__all__ = ["TProtocol", "TBinaryProtocol"] diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py new file mode 100644 index 00000000..52c6118a --- /dev/null +++ b/lib/py/src/transport/TSocket.py @@ -0,0 +1,45 @@ +from TTransport import * +import socket + +class TSocket(TTransportBase): + + """Socket implementation of TTransport base.""" + + handle = None + host = "localhost" + port = 9090 + + def __init__(self, host, port): + self.host = host + self.port = port + self.handle = None + + def isOpen(self): + return handle != None + + def open(self): + self.handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.handle.connect((self.host, self.port)) + + def close(self): + self.handle.close() + self.handle = None + + def readAll(self, sz): + buff = '' + have = 0 + while (have < sz): + chunk = self.read(sz-have) + have += len(chunk) + buff += chunk + return buff + + def read(self, sz): + buff = self.handle.recv(sz) + return buff + + def write(self, buff): + self.handle.sendall(buff) + + def flush(self): + pass diff --git a/lib/py/src/transport/TTransport.py b/lib/py/src/transport/TTransport.py new file mode 100644 index 00000000..e9e36d72 --- /dev/null +++ b/lib/py/src/transport/TTransport.py @@ -0,0 +1,25 @@ +class TTransportBase: + + """Base class for Thrift transport layer.""" + + def isOpen(self): + pass + + def open(self): + pass + + def close(self): + pass + + def read(self, sz): + pass + + def readAll(self, sz): + pass + + def write(self, buf): + pass + + def flush(): + pass + diff --git a/lib/py/src/transport/__init__.py b/lib/py/src/transport/__init__.py new file mode 100644 index 00000000..fb50c8bf --- /dev/null +++ b/lib/py/src/transport/__init__.py @@ -0,0 +1 @@ +__all__ = ["TTransport", "TSocket"] -- 2.17.1