Thrift.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #
  2. # Licensed to the Apache Software Foundation (ASF) under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. The ASF licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing,
  13. # software distributed under the License is distributed on an
  14. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. # KIND, either express or implied. See the License for the
  16. # specific language governing permissions and limitations
  17. # under the License.
  18. #
  19. import sys
  20. class TType(object):
  21. STOP = 0
  22. VOID = 1
  23. BOOL = 2
  24. BYTE = 3
  25. I08 = 3
  26. DOUBLE = 4
  27. I16 = 6
  28. I32 = 8
  29. I64 = 10
  30. STRING = 11
  31. UTF7 = 11
  32. STRUCT = 12
  33. MAP = 13
  34. SET = 14
  35. LIST = 15
  36. UTF8 = 16
  37. UTF16 = 17
  38. _VALUES_TO_NAMES = (
  39. 'STOP',
  40. 'VOID',
  41. 'BOOL',
  42. 'BYTE',
  43. 'DOUBLE',
  44. None,
  45. 'I16',
  46. None,
  47. 'I32',
  48. None,
  49. 'I64',
  50. 'STRING',
  51. 'STRUCT',
  52. 'MAP',
  53. 'SET',
  54. 'LIST',
  55. 'UTF8',
  56. 'UTF16',
  57. )
  58. class TMessageType(object):
  59. CALL = 1
  60. REPLY = 2
  61. EXCEPTION = 3
  62. ONEWAY = 4
  63. class TProcessor(object):
  64. """Base class for processor, which works on two streams."""
  65. def process(self, iprot, oprot):
  66. """
  67. Process a request. The normal behvaior is to have the
  68. processor invoke the correct handler and then it is the
  69. server's responsibility to write the response to oprot.
  70. """
  71. pass
  72. def on_message_begin(self, func):
  73. """
  74. Install a callback that receives (name, type, seqid)
  75. after the message header is read.
  76. """
  77. pass
  78. class TException(Exception):
  79. """Base class for all thrift exceptions."""
  80. # BaseException.message is deprecated in Python v[2.6,3.0)
  81. if (2, 6, 0) <= sys.version_info < (3, 0):
  82. def _get_message(self):
  83. return self._message
  84. def _set_message(self, message):
  85. self._message = message
  86. message = property(_get_message, _set_message)
  87. def __init__(self, message=None):
  88. Exception.__init__(self, message)
  89. self.message = message
  90. class TApplicationException(TException):
  91. """Application level thrift exceptions."""
  92. UNKNOWN = 0
  93. UNKNOWN_METHOD = 1
  94. INVALID_MESSAGE_TYPE = 2
  95. WRONG_METHOD_NAME = 3
  96. BAD_SEQUENCE_ID = 4
  97. MISSING_RESULT = 5
  98. INTERNAL_ERROR = 6
  99. PROTOCOL_ERROR = 7
  100. INVALID_TRANSFORM = 8
  101. INVALID_PROTOCOL = 9
  102. UNSUPPORTED_CLIENT_TYPE = 10
  103. def __init__(self, type=UNKNOWN, message=None):
  104. TException.__init__(self, message)
  105. self.type = type
  106. def __str__(self):
  107. if self.message:
  108. return self.message
  109. elif self.type == self.UNKNOWN_METHOD:
  110. return 'Unknown method'
  111. elif self.type == self.INVALID_MESSAGE_TYPE:
  112. return 'Invalid message type'
  113. elif self.type == self.WRONG_METHOD_NAME:
  114. return 'Wrong method name'
  115. elif self.type == self.BAD_SEQUENCE_ID:
  116. return 'Bad sequence ID'
  117. elif self.type == self.MISSING_RESULT:
  118. return 'Missing result'
  119. elif self.type == self.INTERNAL_ERROR:
  120. return 'Internal error'
  121. elif self.type == self.PROTOCOL_ERROR:
  122. return 'Protocol error'
  123. elif self.type == self.INVALID_TRANSFORM:
  124. return 'Invalid transform'
  125. elif self.type == self.INVALID_PROTOCOL:
  126. return 'Invalid protocol'
  127. elif self.type == self.UNSUPPORTED_CLIENT_TYPE:
  128. return 'Unsupported client type'
  129. else:
  130. return 'Default (unknown) TApplicationException'
  131. def read(self, iprot):
  132. iprot.readStructBegin()
  133. while True:
  134. (fname, ftype, fid) = iprot.readFieldBegin()
  135. if ftype == TType.STOP:
  136. break
  137. if fid == 1:
  138. if ftype == TType.STRING:
  139. self.message = iprot.readString()
  140. else:
  141. iprot.skip(ftype)
  142. elif fid == 2:
  143. if ftype == TType.I32:
  144. self.type = iprot.readI32()
  145. else:
  146. iprot.skip(ftype)
  147. else:
  148. iprot.skip(ftype)
  149. iprot.readFieldEnd()
  150. iprot.readStructEnd()
  151. def write(self, oprot):
  152. oprot.writeStructBegin('TApplicationException')
  153. if self.message is not None:
  154. oprot.writeFieldBegin('message', TType.STRING, 1)
  155. oprot.writeString(self.message)
  156. oprot.writeFieldEnd()
  157. if self.type is not None:
  158. oprot.writeFieldBegin('type', TType.I32, 2)
  159. oprot.writeI32(self.type)
  160. oprot.writeFieldEnd()
  161. oprot.writeFieldStop()
  162. oprot.writeStructEnd()
  163. class TFrozenDict(dict):
  164. """A dictionary that is "frozen" like a frozenset"""
  165. def __init__(self, *args, **kwargs):
  166. super(TFrozenDict, self).__init__(*args, **kwargs)
  167. # Sort the items so they will be in a consistent order.
  168. # XOR in the hash of the class so we don't collide with
  169. # the hash of a list of tuples.
  170. self.__hashval = hash(TFrozenDict) ^ hash(tuple(sorted(self.items())))
  171. def __setitem__(self, *args):
  172. raise TypeError("Can't modify frozen TFreezableDict")
  173. def __delitem__(self, *args):
  174. raise TypeError("Can't modify frozen TFreezableDict")
  175. def __hash__(self):
  176. return self.__hashval