#
# Autogenerated by Thrift Compiler (0.10.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
from thrift.protocol.TProtocol import TProtocolException
import sys
import logging
from .ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport


class Iface(object):
    def login(self, auth_request):
        """
        Parameters:
         - auth_request
        """
        pass

    def set_keyspace(self, keyspace):
        """
        Parameters:
         - keyspace
        """
        pass

    def get(self, key, column_path, consistency_level):
        """
        Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is
        the only method that can throw an exception under non-failure conditions.)

        Parameters:
         - key
         - column_path
         - consistency_level
        """
        pass

    def get_slice(self, key, column_parent, predicate, consistency_level):
        """
        Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name
        pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned.

        Parameters:
         - key
         - column_parent
         - predicate
         - consistency_level
        """
        pass

    def get_count(self, key, column_parent, predicate, consistency_level):
        """
        returns the number of columns matching <code>predicate</code> for a particular <code>key</code>,
        <code>ColumnFamily</code> and optionally <code>SuperColumn</code>.

        Parameters:
         - key
         - column_parent
         - predicate
         - consistency_level
        """
        pass

    def multiget_slice(self, keys, column_parent, predicate, consistency_level):
        """
        Performs a get_slice for column_parent and predicate for the given keys in parallel.

        Parameters:
         - keys
         - column_parent
         - predicate
         - consistency_level
        """
        pass

    def multiget_count(self, keys, column_parent, predicate, consistency_level):
        """
        Perform a get_count in parallel on the given list<binary> keys. The return value maps keys to the count found.

        Parameters:
         - keys
         - column_parent
         - predicate
         - consistency_level
        """
        pass

    def get_range_slices(self, column_parent, predicate, range, consistency_level):
        """
        returns a subset of columns for a contiguous range of keys.

        Parameters:
         - column_parent
         - predicate
         - range
         - consistency_level
        """
        pass

    def get_paged_slice(self, column_family, range, start_column, consistency_level):
        """
        returns a range of columns, wrapping to the next rows if necessary to collect max_results.

        Parameters:
         - column_family
         - range
         - start_column
         - consistency_level
        """
        pass

    def get_indexed_slices(self, column_parent, index_clause, column_predicate, consistency_level):
        """
        Returns the subset of columns specified in SlicePredicate for the rows matching the IndexClause
        @deprecated use get_range_slices instead with range.row_filter specified

        Parameters:
         - column_parent
         - index_clause
         - column_predicate
         - consistency_level
        """
        pass

    def insert(self, key, column_parent, column, consistency_level):
        """
        Insert a Column at the given column_parent.column_family and optional column_parent.super_column.

        Parameters:
         - key
         - column_parent
         - column
         - consistency_level
        """
        pass

    def add(self, key, column_parent, column, consistency_level):
        """
        Increment or decrement a counter.

        Parameters:
         - key
         - column_parent
         - column
         - consistency_level
        """
        pass

    def cas(self, key, column_family, expected, updates, serial_consistency_level, commit_consistency_level):
        """
        Atomic compare and set.

        If the cas is successfull, the success boolean in CASResult will be true and there will be no current_values.
        Otherwise, success will be false and current_values will contain the current values for the columns in
        expected (that, by definition of compare-and-set, will differ from the values in expected).

        A cas operation takes 2 consistency level. The first one, serial_consistency_level, simply indicates the
        level of serialization required. This can be either ConsistencyLevel.SERIAL or ConsistencyLevel.LOCAL_SERIAL.
        The second one, commit_consistency_level, defines the consistency level for the commit phase of the cas. This
        is a more traditional consistency level (the same CL than for traditional writes are accepted) that impact
        the visibility for reads of the operation. For instance, if commit_consistency_level is QUORUM, then it is
        guaranteed that a followup QUORUM read will see the cas write (if that one was successful obviously). If
        commit_consistency_level is ANY, you will need to use a SERIAL/LOCAL_SERIAL read to be guaranteed to see
        the write.

        Parameters:
         - key
         - column_family
         - expected
         - updates
         - serial_consistency_level
         - commit_consistency_level
        """
        pass

    def remove(self, key, column_path, timestamp, consistency_level):
        """
        Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
        that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
        row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.

        Parameters:
         - key
         - column_path
         - timestamp
         - consistency_level
        """
        pass

    def remove_counter(self, key, path, consistency_level):
        """
        Remove a counter at the specified location.
        Note that counters have limited support for deletes: if you remove a counter, you must wait to issue any following update
        until the delete has reached all the nodes and all of them have been fully compacted.

        Parameters:
         - key
         - path
         - consistency_level
        """
        pass

    def batch_mutate(self, mutation_map, consistency_level):
        """
          Mutate many columns or super columns for many row keys. See also: Mutation.

          mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
        *

        Parameters:
         - mutation_map
         - consistency_level
        """
        pass

    def atomic_batch_mutate(self, mutation_map, consistency_level):
        """
          Atomically mutate many columns or super columns for many row keys. See also: Mutation.

          mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
        *

        Parameters:
         - mutation_map
         - consistency_level
        """
        pass

    def truncate(self, cfname):
        """
        Truncate will mark and entire column family as deleted.
        From the user's perspective a successful call to truncate will result complete data deletion from cfname.
        Internally, however, disk space will not be immediatily released, as with all deletes in cassandra, this one
        only marks the data as deleted.
        The operation succeeds only if all hosts in the cluster at available and will throw an UnavailableException if
        some hosts are down.

        Parameters:
         - cfname
        """
        pass

    def get_multi_slice(self, request):
        """
        Select multiple slices of a key in a single RPC operation

        Parameters:
         - request
        """
        pass

    def describe_schema_versions(self):
        """
        for each schema version present in the cluster, returns a list of nodes at that version.
        hosts that do not respond will be under the key DatabaseDescriptor.INITIAL_VERSION.
        the cluster is all on the same version if the size of the map is 1.
        """
        pass

    def describe_keyspaces(self):
        """
        list the defined keyspaces in this cluster
        """
        pass

    def describe_cluster_name(self):
        """
        get the cluster name
        """
        pass

    def describe_version(self):
        """
        get the thrift api version
        """
        pass

    def describe_ring(self, keyspace):
        """
        get the token ring: a map of ranges to host addresses,
        represented as a set of TokenRange instead of a map from range
        to list of endpoints, because you can't use Thrift structs as
        map keys:
        https://issues.apache.org/jira/browse/THRIFT-162

        for the same reason, we can't return a set here, even though
        order is neither important nor predictable.

        Parameters:
         - keyspace
        """
        pass

    def describe_local_ring(self, keyspace):
        """
        same as describe_ring, but considers only nodes in the local DC

        Parameters:
         - keyspace
        """
        pass

    def describe_token_map(self):
        """
        get the mapping between token->node ip
        without taking replication into consideration
        https://issues.apache.org/jira/browse/CASSANDRA-4092
        """
        pass

    def describe_partitioner(self):
        """
        returns the partitioner used by this cluster
        """
        pass

    def describe_snitch(self):
        """
        returns the snitch used by this cluster
        """
        pass

    def describe_keyspace(self, keyspace):
        """
        describe specified keyspace

        Parameters:
         - keyspace
        """
        pass

    def describe_splits(self, cfName, start_token, end_token, keys_per_split):
        """
        experimental API for hadoop/parallel query support.
        may change violently and without warning.

        returns list of token strings such that first subrange is (list[0], list[1]],
        next is (list[1], list[2]], etc.

        Parameters:
         - cfName
         - start_token
         - end_token
         - keys_per_split
        """
        pass

    def trace_next_query(self):
        """
        Enables tracing for the next query in this connection and returns the UUID for that trace session
        The next query will be traced idependently of trace probability and the returned UUID can be used to query the trace keyspace
        """
        pass

    def describe_splits_ex(self, cfName, start_token, end_token, keys_per_split):
        """
        Parameters:
         - cfName
         - start_token
         - end_token
         - keys_per_split
        """
        pass

    def system_add_column_family(self, cf_def):
        """
        adds a column family. returns the new schema id.

        Parameters:
         - cf_def
        """
        pass

    def system_drop_column_family(self, column_family):
        """
        drops a column family. returns the new schema id.

        Parameters:
         - column_family
        """
        pass

    def system_add_keyspace(self, ks_def):
        """
        adds a keyspace and any column families that are part of it. returns the new schema id.

        Parameters:
         - ks_def
        """
        pass

    def system_drop_keyspace(self, keyspace):
        """
        drops a keyspace and any column families that are part of it. returns the new schema id.

        Parameters:
         - keyspace
        """
        pass

    def system_update_keyspace(self, ks_def):
        """
        updates properties of a keyspace. returns the new schema id.

        Parameters:
         - ks_def
        """
        pass

    def system_update_column_family(self, cf_def):
        """
        updates properties of a column family. returns the new schema id.

        Parameters:
         - cf_def
        """
        pass

    def execute_cql_query(self, query, compression):
        """
        @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.

        Parameters:
         - query
         - compression
        """
        pass

    def execute_cql3_query(self, query, compression, consistency):
        """
        Executes a CQL3 (Cassandra Query Language) statement and returns a
        CqlResult containing the results.

        Parameters:
         - query
         - compression
         - consistency
        """
        pass

    def prepare_cql_query(self, query, compression):
        """
        @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.

        Parameters:
         - query
         - compression
        """
        pass

    def prepare_cql3_query(self, query, compression):
        """
        Prepare a CQL3 (Cassandra Query Language) statement by compiling and returning
        - the type of CQL statement
        - an id token of the compiled CQL stored on the server side.
        - a count of the discovered bound markers in the statement

        Parameters:
         - query
         - compression
        """
        pass

    def execute_prepared_cql_query(self, itemId, values):
        """
        @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.

        Parameters:
         - itemId
         - values
        """
        pass

    def execute_prepared_cql3_query(self, itemId, values, consistency):
        """
        Executes a prepared CQL3 (Cassandra Query Language) statement by passing an id token, a list of variables
        to bind, and the consistency level, and returns a CqlResult containing the results.

        Parameters:
         - itemId
         - values
         - consistency
        """
        pass

    def set_cql_version(self, version):
        """
        @deprecated This is now a no-op. Please use the CQL3 specific methods instead.

        Parameters:
         - version
        """
        pass


class Client(Iface):
    def __init__(self, iprot, oprot=None):
        self._iprot = self._oprot = iprot
        if oprot is not None:
            self._oprot = oprot
        self._seqid = 0

    def login(self, auth_request):
        """
        Parameters:
         - auth_request
        """
        self.send_login(auth_request)
        self.recv_login()

    def send_login(self, auth_request):
        self._oprot.writeMessageBegin('login', TMessageType.CALL, self._seqid)
        args = login_args()
        args.auth_request = auth_request
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_login(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = login_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.authnx is not None:
            raise result.authnx
        if result.authzx is not None:
            raise result.authzx
        return

    def set_keyspace(self, keyspace):
        """
        Parameters:
         - keyspace
        """
        self.send_set_keyspace(keyspace)
        self.recv_set_keyspace()

    def send_set_keyspace(self, keyspace):
        self._oprot.writeMessageBegin('set_keyspace', TMessageType.CALL, self._seqid)
        args = set_keyspace_args()
        args.keyspace = keyspace
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_set_keyspace(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = set_keyspace_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        return

    def get(self, key, column_path, consistency_level):
        """
        Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is
        the only method that can throw an exception under non-failure conditions.)

        Parameters:
         - key
         - column_path
         - consistency_level
        """
        self.send_get(key, column_path, consistency_level)
        return self.recv_get()

    def send_get(self, key, column_path, consistency_level):
        self._oprot.writeMessageBegin('get', TMessageType.CALL, self._seqid)
        args = get_args()
        args.key = key
        args.column_path = column_path
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.nfe is not None:
            raise result.nfe
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get failed: unknown result")

    def get_slice(self, key, column_parent, predicate, consistency_level):
        """
        Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name
        pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned.

        Parameters:
         - key
         - column_parent
         - predicate
         - consistency_level
        """
        self.send_get_slice(key, column_parent, predicate, consistency_level)
        return self.recv_get_slice()

    def send_get_slice(self, key, column_parent, predicate, consistency_level):
        self._oprot.writeMessageBegin('get_slice', TMessageType.CALL, self._seqid)
        args = get_slice_args()
        args.key = key
        args.column_parent = column_parent
        args.predicate = predicate
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get_slice(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_slice_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get_slice failed: unknown result")

    def get_count(self, key, column_parent, predicate, consistency_level):
        """
        returns the number of columns matching <code>predicate</code> for a particular <code>key</code>,
        <code>ColumnFamily</code> and optionally <code>SuperColumn</code>.

        Parameters:
         - key
         - column_parent
         - predicate
         - consistency_level
        """
        self.send_get_count(key, column_parent, predicate, consistency_level)
        return self.recv_get_count()

    def send_get_count(self, key, column_parent, predicate, consistency_level):
        self._oprot.writeMessageBegin('get_count', TMessageType.CALL, self._seqid)
        args = get_count_args()
        args.key = key
        args.column_parent = column_parent
        args.predicate = predicate
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get_count(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_count_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get_count failed: unknown result")

    def multiget_slice(self, keys, column_parent, predicate, consistency_level):
        """
        Performs a get_slice for column_parent and predicate for the given keys in parallel.

        Parameters:
         - keys
         - column_parent
         - predicate
         - consistency_level
        """
        self.send_multiget_slice(keys, column_parent, predicate, consistency_level)
        return self.recv_multiget_slice()

    def send_multiget_slice(self, keys, column_parent, predicate, consistency_level):
        self._oprot.writeMessageBegin('multiget_slice', TMessageType.CALL, self._seqid)
        args = multiget_slice_args()
        args.keys = keys
        args.column_parent = column_parent
        args.predicate = predicate
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_multiget_slice(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = multiget_slice_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "multiget_slice failed: unknown result")

    def multiget_count(self, keys, column_parent, predicate, consistency_level):
        """
        Perform a get_count in parallel on the given list<binary> keys. The return value maps keys to the count found.

        Parameters:
         - keys
         - column_parent
         - predicate
         - consistency_level
        """
        self.send_multiget_count(keys, column_parent, predicate, consistency_level)
        return self.recv_multiget_count()

    def send_multiget_count(self, keys, column_parent, predicate, consistency_level):
        self._oprot.writeMessageBegin('multiget_count', TMessageType.CALL, self._seqid)
        args = multiget_count_args()
        args.keys = keys
        args.column_parent = column_parent
        args.predicate = predicate
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_multiget_count(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = multiget_count_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "multiget_count failed: unknown result")

    def get_range_slices(self, column_parent, predicate, range, consistency_level):
        """
        returns a subset of columns for a contiguous range of keys.

        Parameters:
         - column_parent
         - predicate
         - range
         - consistency_level
        """
        self.send_get_range_slices(column_parent, predicate, range, consistency_level)
        return self.recv_get_range_slices()

    def send_get_range_slices(self, column_parent, predicate, range, consistency_level):
        self._oprot.writeMessageBegin('get_range_slices', TMessageType.CALL, self._seqid)
        args = get_range_slices_args()
        args.column_parent = column_parent
        args.predicate = predicate
        args.range = range
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get_range_slices(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_range_slices_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get_range_slices failed: unknown result")

    def get_paged_slice(self, column_family, range, start_column, consistency_level):
        """
        returns a range of columns, wrapping to the next rows if necessary to collect max_results.

        Parameters:
         - column_family
         - range
         - start_column
         - consistency_level
        """
        self.send_get_paged_slice(column_family, range, start_column, consistency_level)
        return self.recv_get_paged_slice()

    def send_get_paged_slice(self, column_family, range, start_column, consistency_level):
        self._oprot.writeMessageBegin('get_paged_slice', TMessageType.CALL, self._seqid)
        args = get_paged_slice_args()
        args.column_family = column_family
        args.range = range
        args.start_column = start_column
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get_paged_slice(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_paged_slice_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get_paged_slice failed: unknown result")

    def get_indexed_slices(self, column_parent, index_clause, column_predicate, consistency_level):
        """
        Returns the subset of columns specified in SlicePredicate for the rows matching the IndexClause
        @deprecated use get_range_slices instead with range.row_filter specified

        Parameters:
         - column_parent
         - index_clause
         - column_predicate
         - consistency_level
        """
        self.send_get_indexed_slices(column_parent, index_clause, column_predicate, consistency_level)
        return self.recv_get_indexed_slices()

    def send_get_indexed_slices(self, column_parent, index_clause, column_predicate, consistency_level):
        self._oprot.writeMessageBegin('get_indexed_slices', TMessageType.CALL, self._seqid)
        args = get_indexed_slices_args()
        args.column_parent = column_parent
        args.index_clause = index_clause
        args.column_predicate = column_predicate
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get_indexed_slices(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_indexed_slices_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get_indexed_slices failed: unknown result")

    def insert(self, key, column_parent, column, consistency_level):
        """
        Insert a Column at the given column_parent.column_family and optional column_parent.super_column.

        Parameters:
         - key
         - column_parent
         - column
         - consistency_level
        """
        self.send_insert(key, column_parent, column, consistency_level)
        self.recv_insert()

    def send_insert(self, key, column_parent, column, consistency_level):
        self._oprot.writeMessageBegin('insert', TMessageType.CALL, self._seqid)
        args = insert_args()
        args.key = key
        args.column_parent = column_parent
        args.column = column
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_insert(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = insert_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def add(self, key, column_parent, column, consistency_level):
        """
        Increment or decrement a counter.

        Parameters:
         - key
         - column_parent
         - column
         - consistency_level
        """
        self.send_add(key, column_parent, column, consistency_level)
        self.recv_add()

    def send_add(self, key, column_parent, column, consistency_level):
        self._oprot.writeMessageBegin('add', TMessageType.CALL, self._seqid)
        args = add_args()
        args.key = key
        args.column_parent = column_parent
        args.column = column
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_add(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = add_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def cas(self, key, column_family, expected, updates, serial_consistency_level, commit_consistency_level):
        """
        Atomic compare and set.

        If the cas is successfull, the success boolean in CASResult will be true and there will be no current_values.
        Otherwise, success will be false and current_values will contain the current values for the columns in
        expected (that, by definition of compare-and-set, will differ from the values in expected).

        A cas operation takes 2 consistency level. The first one, serial_consistency_level, simply indicates the
        level of serialization required. This can be either ConsistencyLevel.SERIAL or ConsistencyLevel.LOCAL_SERIAL.
        The second one, commit_consistency_level, defines the consistency level for the commit phase of the cas. This
        is a more traditional consistency level (the same CL than for traditional writes are accepted) that impact
        the visibility for reads of the operation. For instance, if commit_consistency_level is QUORUM, then it is
        guaranteed that a followup QUORUM read will see the cas write (if that one was successful obviously). If
        commit_consistency_level is ANY, you will need to use a SERIAL/LOCAL_SERIAL read to be guaranteed to see
        the write.

        Parameters:
         - key
         - column_family
         - expected
         - updates
         - serial_consistency_level
         - commit_consistency_level
        """
        self.send_cas(key, column_family, expected, updates, serial_consistency_level, commit_consistency_level)
        return self.recv_cas()

    def send_cas(self, key, column_family, expected, updates, serial_consistency_level, commit_consistency_level):
        self._oprot.writeMessageBegin('cas', TMessageType.CALL, self._seqid)
        args = cas_args()
        args.key = key
        args.column_family = column_family
        args.expected = expected
        args.updates = updates
        args.serial_consistency_level = serial_consistency_level
        args.commit_consistency_level = commit_consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_cas(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = cas_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "cas failed: unknown result")

    def remove(self, key, column_path, timestamp, consistency_level):
        """
        Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
        that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
        row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.

        Parameters:
         - key
         - column_path
         - timestamp
         - consistency_level
        """
        self.send_remove(key, column_path, timestamp, consistency_level)
        self.recv_remove()

    def send_remove(self, key, column_path, timestamp, consistency_level):
        self._oprot.writeMessageBegin('remove', TMessageType.CALL, self._seqid)
        args = remove_args()
        args.key = key
        args.column_path = column_path
        args.timestamp = timestamp
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_remove(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = remove_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def remove_counter(self, key, path, consistency_level):
        """
        Remove a counter at the specified location.
        Note that counters have limited support for deletes: if you remove a counter, you must wait to issue any following update
        until the delete has reached all the nodes and all of them have been fully compacted.

        Parameters:
         - key
         - path
         - consistency_level
        """
        self.send_remove_counter(key, path, consistency_level)
        self.recv_remove_counter()

    def send_remove_counter(self, key, path, consistency_level):
        self._oprot.writeMessageBegin('remove_counter', TMessageType.CALL, self._seqid)
        args = remove_counter_args()
        args.key = key
        args.path = path
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_remove_counter(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = remove_counter_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def batch_mutate(self, mutation_map, consistency_level):
        """
          Mutate many columns or super columns for many row keys. See also: Mutation.

          mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
        *

        Parameters:
         - mutation_map
         - consistency_level
        """
        self.send_batch_mutate(mutation_map, consistency_level)
        self.recv_batch_mutate()

    def send_batch_mutate(self, mutation_map, consistency_level):
        self._oprot.writeMessageBegin('batch_mutate', TMessageType.CALL, self._seqid)
        args = batch_mutate_args()
        args.mutation_map = mutation_map
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_batch_mutate(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = batch_mutate_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def atomic_batch_mutate(self, mutation_map, consistency_level):
        """
          Atomically mutate many columns or super columns for many row keys. See also: Mutation.

          mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
        *

        Parameters:
         - mutation_map
         - consistency_level
        """
        self.send_atomic_batch_mutate(mutation_map, consistency_level)
        self.recv_atomic_batch_mutate()

    def send_atomic_batch_mutate(self, mutation_map, consistency_level):
        self._oprot.writeMessageBegin('atomic_batch_mutate', TMessageType.CALL, self._seqid)
        args = atomic_batch_mutate_args()
        args.mutation_map = mutation_map
        args.consistency_level = consistency_level
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_atomic_batch_mutate(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = atomic_batch_mutate_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def truncate(self, cfname):
        """
        Truncate will mark and entire column family as deleted.
        From the user's perspective a successful call to truncate will result complete data deletion from cfname.
        Internally, however, disk space will not be immediatily released, as with all deletes in cassandra, this one
        only marks the data as deleted.
        The operation succeeds only if all hosts in the cluster at available and will throw an UnavailableException if
        some hosts are down.

        Parameters:
         - cfname
        """
        self.send_truncate(cfname)
        self.recv_truncate()

    def send_truncate(self, cfname):
        self._oprot.writeMessageBegin('truncate', TMessageType.CALL, self._seqid)
        args = truncate_args()
        args.cfname = cfname
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_truncate(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = truncate_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        return

    def get_multi_slice(self, request):
        """
        Select multiple slices of a key in a single RPC operation

        Parameters:
         - request
        """
        self.send_get_multi_slice(request)
        return self.recv_get_multi_slice()

    def send_get_multi_slice(self, request):
        self._oprot.writeMessageBegin('get_multi_slice', TMessageType.CALL, self._seqid)
        args = get_multi_slice_args()
        args.request = request
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_get_multi_slice(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = get_multi_slice_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        raise TApplicationException(TApplicationException.MISSING_RESULT, "get_multi_slice failed: unknown result")

    def describe_schema_versions(self):
        """
        for each schema version present in the cluster, returns a list of nodes at that version.
        hosts that do not respond will be under the key DatabaseDescriptor.INITIAL_VERSION.
        the cluster is all on the same version if the size of the map is 1.
        """
        self.send_describe_schema_versions()
        return self.recv_describe_schema_versions()

    def send_describe_schema_versions(self):
        self._oprot.writeMessageBegin('describe_schema_versions', TMessageType.CALL, self._seqid)
        args = describe_schema_versions_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_schema_versions(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_schema_versions_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_schema_versions failed: unknown result")

    def describe_keyspaces(self):
        """
        list the defined keyspaces in this cluster
        """
        self.send_describe_keyspaces()
        return self.recv_describe_keyspaces()

    def send_describe_keyspaces(self):
        self._oprot.writeMessageBegin('describe_keyspaces', TMessageType.CALL, self._seqid)
        args = describe_keyspaces_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_keyspaces(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_keyspaces_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_keyspaces failed: unknown result")

    def describe_cluster_name(self):
        """
        get the cluster name
        """
        self.send_describe_cluster_name()
        return self.recv_describe_cluster_name()

    def send_describe_cluster_name(self):
        self._oprot.writeMessageBegin('describe_cluster_name', TMessageType.CALL, self._seqid)
        args = describe_cluster_name_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_cluster_name(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_cluster_name_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_cluster_name failed: unknown result")

    def describe_version(self):
        """
        get the thrift api version
        """
        self.send_describe_version()
        return self.recv_describe_version()

    def send_describe_version(self):
        self._oprot.writeMessageBegin('describe_version', TMessageType.CALL, self._seqid)
        args = describe_version_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_version(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_version_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_version failed: unknown result")

    def describe_ring(self, keyspace):
        """
        get the token ring: a map of ranges to host addresses,
        represented as a set of TokenRange instead of a map from range
        to list of endpoints, because you can't use Thrift structs as
        map keys:
        https://issues.apache.org/jira/browse/THRIFT-162

        for the same reason, we can't return a set here, even though
        order is neither important nor predictable.

        Parameters:
         - keyspace
        """
        self.send_describe_ring(keyspace)
        return self.recv_describe_ring()

    def send_describe_ring(self, keyspace):
        self._oprot.writeMessageBegin('describe_ring', TMessageType.CALL, self._seqid)
        args = describe_ring_args()
        args.keyspace = keyspace
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_ring(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_ring_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_ring failed: unknown result")

    def describe_local_ring(self, keyspace):
        """
        same as describe_ring, but considers only nodes in the local DC

        Parameters:
         - keyspace
        """
        self.send_describe_local_ring(keyspace)
        return self.recv_describe_local_ring()

    def send_describe_local_ring(self, keyspace):
        self._oprot.writeMessageBegin('describe_local_ring', TMessageType.CALL, self._seqid)
        args = describe_local_ring_args()
        args.keyspace = keyspace
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_local_ring(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_local_ring_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_local_ring failed: unknown result")

    def describe_token_map(self):
        """
        get the mapping between token->node ip
        without taking replication into consideration
        https://issues.apache.org/jira/browse/CASSANDRA-4092
        """
        self.send_describe_token_map()
        return self.recv_describe_token_map()

    def send_describe_token_map(self):
        self._oprot.writeMessageBegin('describe_token_map', TMessageType.CALL, self._seqid)
        args = describe_token_map_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_token_map(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_token_map_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_token_map failed: unknown result")

    def describe_partitioner(self):
        """
        returns the partitioner used by this cluster
        """
        self.send_describe_partitioner()
        return self.recv_describe_partitioner()

    def send_describe_partitioner(self):
        self._oprot.writeMessageBegin('describe_partitioner', TMessageType.CALL, self._seqid)
        args = describe_partitioner_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_partitioner(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_partitioner_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_partitioner failed: unknown result")

    def describe_snitch(self):
        """
        returns the snitch used by this cluster
        """
        self.send_describe_snitch()
        return self.recv_describe_snitch()

    def send_describe_snitch(self):
        self._oprot.writeMessageBegin('describe_snitch', TMessageType.CALL, self._seqid)
        args = describe_snitch_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_snitch(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_snitch_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_snitch failed: unknown result")

    def describe_keyspace(self, keyspace):
        """
        describe specified keyspace

        Parameters:
         - keyspace
        """
        self.send_describe_keyspace(keyspace)
        return self.recv_describe_keyspace()

    def send_describe_keyspace(self, keyspace):
        self._oprot.writeMessageBegin('describe_keyspace', TMessageType.CALL, self._seqid)
        args = describe_keyspace_args()
        args.keyspace = keyspace
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_keyspace(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_keyspace_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.nfe is not None:
            raise result.nfe
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_keyspace failed: unknown result")

    def describe_splits(self, cfName, start_token, end_token, keys_per_split):
        """
        experimental API for hadoop/parallel query support.
        may change violently and without warning.

        returns list of token strings such that first subrange is (list[0], list[1]],
        next is (list[1], list[2]], etc.

        Parameters:
         - cfName
         - start_token
         - end_token
         - keys_per_split
        """
        self.send_describe_splits(cfName, start_token, end_token, keys_per_split)
        return self.recv_describe_splits()

    def send_describe_splits(self, cfName, start_token, end_token, keys_per_split):
        self._oprot.writeMessageBegin('describe_splits', TMessageType.CALL, self._seqid)
        args = describe_splits_args()
        args.cfName = cfName
        args.start_token = start_token
        args.end_token = end_token
        args.keys_per_split = keys_per_split
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_splits(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_splits_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_splits failed: unknown result")

    def trace_next_query(self):
        """
        Enables tracing for the next query in this connection and returns the UUID for that trace session
        The next query will be traced idependently of trace probability and the returned UUID can be used to query the trace keyspace
        """
        self.send_trace_next_query()
        return self.recv_trace_next_query()

    def send_trace_next_query(self):
        self._oprot.writeMessageBegin('trace_next_query', TMessageType.CALL, self._seqid)
        args = trace_next_query_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_trace_next_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = trace_next_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "trace_next_query failed: unknown result")

    def describe_splits_ex(self, cfName, start_token, end_token, keys_per_split):
        """
        Parameters:
         - cfName
         - start_token
         - end_token
         - keys_per_split
        """
        self.send_describe_splits_ex(cfName, start_token, end_token, keys_per_split)
        return self.recv_describe_splits_ex()

    def send_describe_splits_ex(self, cfName, start_token, end_token, keys_per_split):
        self._oprot.writeMessageBegin('describe_splits_ex', TMessageType.CALL, self._seqid)
        args = describe_splits_ex_args()
        args.cfName = cfName
        args.start_token = start_token
        args.end_token = end_token
        args.keys_per_split = keys_per_split
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_describe_splits_ex(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = describe_splits_ex_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_splits_ex failed: unknown result")

    def system_add_column_family(self, cf_def):
        """
        adds a column family. returns the new schema id.

        Parameters:
         - cf_def
        """
        self.send_system_add_column_family(cf_def)
        return self.recv_system_add_column_family()

    def send_system_add_column_family(self, cf_def):
        self._oprot.writeMessageBegin('system_add_column_family', TMessageType.CALL, self._seqid)
        args = system_add_column_family_args()
        args.cf_def = cf_def
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_system_add_column_family(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = system_add_column_family_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "system_add_column_family failed: unknown result")

    def system_drop_column_family(self, column_family):
        """
        drops a column family. returns the new schema id.

        Parameters:
         - column_family
        """
        self.send_system_drop_column_family(column_family)
        return self.recv_system_drop_column_family()

    def send_system_drop_column_family(self, column_family):
        self._oprot.writeMessageBegin('system_drop_column_family', TMessageType.CALL, self._seqid)
        args = system_drop_column_family_args()
        args.column_family = column_family
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_system_drop_column_family(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = system_drop_column_family_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "system_drop_column_family failed: unknown result")

    def system_add_keyspace(self, ks_def):
        """
        adds a keyspace and any column families that are part of it. returns the new schema id.

        Parameters:
         - ks_def
        """
        self.send_system_add_keyspace(ks_def)
        return self.recv_system_add_keyspace()

    def send_system_add_keyspace(self, ks_def):
        self._oprot.writeMessageBegin('system_add_keyspace', TMessageType.CALL, self._seqid)
        args = system_add_keyspace_args()
        args.ks_def = ks_def
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_system_add_keyspace(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = system_add_keyspace_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "system_add_keyspace failed: unknown result")

    def system_drop_keyspace(self, keyspace):
        """
        drops a keyspace and any column families that are part of it. returns the new schema id.

        Parameters:
         - keyspace
        """
        self.send_system_drop_keyspace(keyspace)
        return self.recv_system_drop_keyspace()

    def send_system_drop_keyspace(self, keyspace):
        self._oprot.writeMessageBegin('system_drop_keyspace', TMessageType.CALL, self._seqid)
        args = system_drop_keyspace_args()
        args.keyspace = keyspace
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_system_drop_keyspace(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = system_drop_keyspace_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "system_drop_keyspace failed: unknown result")

    def system_update_keyspace(self, ks_def):
        """
        updates properties of a keyspace. returns the new schema id.

        Parameters:
         - ks_def
        """
        self.send_system_update_keyspace(ks_def)
        return self.recv_system_update_keyspace()

    def send_system_update_keyspace(self, ks_def):
        self._oprot.writeMessageBegin('system_update_keyspace', TMessageType.CALL, self._seqid)
        args = system_update_keyspace_args()
        args.ks_def = ks_def
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_system_update_keyspace(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = system_update_keyspace_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "system_update_keyspace failed: unknown result")

    def system_update_column_family(self, cf_def):
        """
        updates properties of a column family. returns the new schema id.

        Parameters:
         - cf_def
        """
        self.send_system_update_column_family(cf_def)
        return self.recv_system_update_column_family()

    def send_system_update_column_family(self, cf_def):
        self._oprot.writeMessageBegin('system_update_column_family', TMessageType.CALL, self._seqid)
        args = system_update_column_family_args()
        args.cf_def = cf_def
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_system_update_column_family(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = system_update_column_family_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "system_update_column_family failed: unknown result")

    def execute_cql_query(self, query, compression):
        """
        @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.

        Parameters:
         - query
         - compression
        """
        self.send_execute_cql_query(query, compression)
        return self.recv_execute_cql_query()

    def send_execute_cql_query(self, query, compression):
        self._oprot.writeMessageBegin('execute_cql_query', TMessageType.CALL, self._seqid)
        args = execute_cql_query_args()
        args.query = query
        args.compression = compression
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_execute_cql_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = execute_cql_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "execute_cql_query failed: unknown result")

    def execute_cql3_query(self, query, compression, consistency):
        """
        Executes a CQL3 (Cassandra Query Language) statement and returns a
        CqlResult containing the results.

        Parameters:
         - query
         - compression
         - consistency
        """
        self.send_execute_cql3_query(query, compression, consistency)
        return self.recv_execute_cql3_query()

    def send_execute_cql3_query(self, query, compression, consistency):
        self._oprot.writeMessageBegin('execute_cql3_query', TMessageType.CALL, self._seqid)
        args = execute_cql3_query_args()
        args.query = query
        args.compression = compression
        args.consistency = consistency
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_execute_cql3_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = execute_cql3_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "execute_cql3_query failed: unknown result")

    def prepare_cql_query(self, query, compression):
        """
        @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.

        Parameters:
         - query
         - compression
        """
        self.send_prepare_cql_query(query, compression)
        return self.recv_prepare_cql_query()

    def send_prepare_cql_query(self, query, compression):
        self._oprot.writeMessageBegin('prepare_cql_query', TMessageType.CALL, self._seqid)
        args = prepare_cql_query_args()
        args.query = query
        args.compression = compression
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_prepare_cql_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = prepare_cql_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "prepare_cql_query failed: unknown result")

    def prepare_cql3_query(self, query, compression):
        """
        Prepare a CQL3 (Cassandra Query Language) statement by compiling and returning
        - the type of CQL statement
        - an id token of the compiled CQL stored on the server side.
        - a count of the discovered bound markers in the statement

        Parameters:
         - query
         - compression
        """
        self.send_prepare_cql3_query(query, compression)
        return self.recv_prepare_cql3_query()

    def send_prepare_cql3_query(self, query, compression):
        self._oprot.writeMessageBegin('prepare_cql3_query', TMessageType.CALL, self._seqid)
        args = prepare_cql3_query_args()
        args.query = query
        args.compression = compression
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_prepare_cql3_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = prepare_cql3_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        raise TApplicationException(TApplicationException.MISSING_RESULT, "prepare_cql3_query failed: unknown result")

    def execute_prepared_cql_query(self, itemId, values):
        """
        @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.

        Parameters:
         - itemId
         - values
        """
        self.send_execute_prepared_cql_query(itemId, values)
        return self.recv_execute_prepared_cql_query()

    def send_execute_prepared_cql_query(self, itemId, values):
        self._oprot.writeMessageBegin('execute_prepared_cql_query', TMessageType.CALL, self._seqid)
        args = execute_prepared_cql_query_args()
        args.itemId = itemId
        args.values = values
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_execute_prepared_cql_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = execute_prepared_cql_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "execute_prepared_cql_query failed: unknown result")

    def execute_prepared_cql3_query(self, itemId, values, consistency):
        """
        Executes a prepared CQL3 (Cassandra Query Language) statement by passing an id token, a list of variables
        to bind, and the consistency level, and returns a CqlResult containing the results.

        Parameters:
         - itemId
         - values
         - consistency
        """
        self.send_execute_prepared_cql3_query(itemId, values, consistency)
        return self.recv_execute_prepared_cql3_query()

    def send_execute_prepared_cql3_query(self, itemId, values, consistency):
        self._oprot.writeMessageBegin('execute_prepared_cql3_query', TMessageType.CALL, self._seqid)
        args = execute_prepared_cql3_query_args()
        args.itemId = itemId
        args.values = values
        args.consistency = consistency
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_execute_prepared_cql3_query(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = execute_prepared_cql3_query_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.ire is not None:
            raise result.ire
        if result.ue is not None:
            raise result.ue
        if result.te is not None:
            raise result.te
        if result.sde is not None:
            raise result.sde
        raise TApplicationException(TApplicationException.MISSING_RESULT, "execute_prepared_cql3_query failed: unknown result")

    def set_cql_version(self, version):
        """
        @deprecated This is now a no-op. Please use the CQL3 specific methods instead.

        Parameters:
         - version
        """
        self.send_set_cql_version(version)
        self.recv_set_cql_version()

    def send_set_cql_version(self, version):
        self._oprot.writeMessageBegin('set_cql_version', TMessageType.CALL, self._seqid)
        args = set_cql_version_args()
        args.version = version
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_set_cql_version(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = set_cql_version_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.ire is not None:
            raise result.ire
        return


class Processor(Iface, TProcessor):
    def __init__(self, handler):
        self._handler = handler
        self._processMap = {}
        self._processMap["login"] = Processor.process_login
        self._processMap["set_keyspace"] = Processor.process_set_keyspace
        self._processMap["get"] = Processor.process_get
        self._processMap["get_slice"] = Processor.process_get_slice
        self._processMap["get_count"] = Processor.process_get_count
        self._processMap["multiget_slice"] = Processor.process_multiget_slice
        self._processMap["multiget_count"] = Processor.process_multiget_count
        self._processMap["get_range_slices"] = Processor.process_get_range_slices
        self._processMap["get_paged_slice"] = Processor.process_get_paged_slice
        self._processMap["get_indexed_slices"] = Processor.process_get_indexed_slices
        self._processMap["insert"] = Processor.process_insert
        self._processMap["add"] = Processor.process_add
        self._processMap["cas"] = Processor.process_cas
        self._processMap["remove"] = Processor.process_remove
        self._processMap["remove_counter"] = Processor.process_remove_counter
        self._processMap["batch_mutate"] = Processor.process_batch_mutate
        self._processMap["atomic_batch_mutate"] = Processor.process_atomic_batch_mutate
        self._processMap["truncate"] = Processor.process_truncate
        self._processMap["get_multi_slice"] = Processor.process_get_multi_slice
        self._processMap["describe_schema_versions"] = Processor.process_describe_schema_versions
        self._processMap["describe_keyspaces"] = Processor.process_describe_keyspaces
        self._processMap["describe_cluster_name"] = Processor.process_describe_cluster_name
        self._processMap["describe_version"] = Processor.process_describe_version
        self._processMap["describe_ring"] = Processor.process_describe_ring
        self._processMap["describe_local_ring"] = Processor.process_describe_local_ring
        self._processMap["describe_token_map"] = Processor.process_describe_token_map
        self._processMap["describe_partitioner"] = Processor.process_describe_partitioner
        self._processMap["describe_snitch"] = Processor.process_describe_snitch
        self._processMap["describe_keyspace"] = Processor.process_describe_keyspace
        self._processMap["describe_splits"] = Processor.process_describe_splits
        self._processMap["trace_next_query"] = Processor.process_trace_next_query
        self._processMap["describe_splits_ex"] = Processor.process_describe_splits_ex
        self._processMap["system_add_column_family"] = Processor.process_system_add_column_family
        self._processMap["system_drop_column_family"] = Processor.process_system_drop_column_family
        self._processMap["system_add_keyspace"] = Processor.process_system_add_keyspace
        self._processMap["system_drop_keyspace"] = Processor.process_system_drop_keyspace
        self._processMap["system_update_keyspace"] = Processor.process_system_update_keyspace
        self._processMap["system_update_column_family"] = Processor.process_system_update_column_family
        self._processMap["execute_cql_query"] = Processor.process_execute_cql_query
        self._processMap["execute_cql3_query"] = Processor.process_execute_cql3_query
        self._processMap["prepare_cql_query"] = Processor.process_prepare_cql_query
        self._processMap["prepare_cql3_query"] = Processor.process_prepare_cql3_query
        self._processMap["execute_prepared_cql_query"] = Processor.process_execute_prepared_cql_query
        self._processMap["execute_prepared_cql3_query"] = Processor.process_execute_prepared_cql3_query
        self._processMap["set_cql_version"] = Processor.process_set_cql_version

    def process(self, iprot, oprot):
        (name, type, seqid) = iprot.readMessageBegin()
        if name not in self._processMap:
            iprot.skip(TType.STRUCT)
            iprot.readMessageEnd()
            x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
            oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
            x.write(oprot)
            oprot.writeMessageEnd()
            oprot.trans.flush()
            return
        else:
            self._processMap[name](self, seqid, iprot, oprot)
        return True

    def process_login(self, seqid, iprot, oprot):
        args = login_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = login_result()
        try:
            self._handler.login(args.auth_request)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except AuthenticationException as authnx:
            msg_type = TMessageType.REPLY
            result.authnx = authnx
        except AuthorizationException as authzx:
            msg_type = TMessageType.REPLY
            result.authzx = authzx
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("login", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_set_keyspace(self, seqid, iprot, oprot):
        args = set_keyspace_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = set_keyspace_result()
        try:
            self._handler.set_keyspace(args.keyspace)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("set_keyspace", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get(self, seqid, iprot, oprot):
        args = get_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_result()
        try:
            result.success = self._handler.get(args.key, args.column_path, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except NotFoundException as nfe:
            msg_type = TMessageType.REPLY
            result.nfe = nfe
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get_slice(self, seqid, iprot, oprot):
        args = get_slice_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_slice_result()
        try:
            result.success = self._handler.get_slice(args.key, args.column_parent, args.predicate, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get_slice", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get_count(self, seqid, iprot, oprot):
        args = get_count_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_count_result()
        try:
            result.success = self._handler.get_count(args.key, args.column_parent, args.predicate, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get_count", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_multiget_slice(self, seqid, iprot, oprot):
        args = multiget_slice_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = multiget_slice_result()
        try:
            result.success = self._handler.multiget_slice(args.keys, args.column_parent, args.predicate, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("multiget_slice", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_multiget_count(self, seqid, iprot, oprot):
        args = multiget_count_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = multiget_count_result()
        try:
            result.success = self._handler.multiget_count(args.keys, args.column_parent, args.predicate, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("multiget_count", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get_range_slices(self, seqid, iprot, oprot):
        args = get_range_slices_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_range_slices_result()
        try:
            result.success = self._handler.get_range_slices(args.column_parent, args.predicate, args.range, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get_range_slices", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get_paged_slice(self, seqid, iprot, oprot):
        args = get_paged_slice_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_paged_slice_result()
        try:
            result.success = self._handler.get_paged_slice(args.column_family, args.range, args.start_column, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get_paged_slice", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get_indexed_slices(self, seqid, iprot, oprot):
        args = get_indexed_slices_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_indexed_slices_result()
        try:
            result.success = self._handler.get_indexed_slices(args.column_parent, args.index_clause, args.column_predicate, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get_indexed_slices", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_insert(self, seqid, iprot, oprot):
        args = insert_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = insert_result()
        try:
            self._handler.insert(args.key, args.column_parent, args.column, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("insert", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_add(self, seqid, iprot, oprot):
        args = add_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = add_result()
        try:
            self._handler.add(args.key, args.column_parent, args.column, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("add", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_cas(self, seqid, iprot, oprot):
        args = cas_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = cas_result()
        try:
            result.success = self._handler.cas(args.key, args.column_family, args.expected, args.updates, args.serial_consistency_level, args.commit_consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("cas", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_remove(self, seqid, iprot, oprot):
        args = remove_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = remove_result()
        try:
            self._handler.remove(args.key, args.column_path, args.timestamp, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("remove", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_remove_counter(self, seqid, iprot, oprot):
        args = remove_counter_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = remove_counter_result()
        try:
            self._handler.remove_counter(args.key, args.path, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("remove_counter", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_batch_mutate(self, seqid, iprot, oprot):
        args = batch_mutate_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = batch_mutate_result()
        try:
            self._handler.batch_mutate(args.mutation_map, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("batch_mutate", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_atomic_batch_mutate(self, seqid, iprot, oprot):
        args = atomic_batch_mutate_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = atomic_batch_mutate_result()
        try:
            self._handler.atomic_batch_mutate(args.mutation_map, args.consistency_level)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("atomic_batch_mutate", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_truncate(self, seqid, iprot, oprot):
        args = truncate_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = truncate_result()
        try:
            self._handler.truncate(args.cfname)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("truncate", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_get_multi_slice(self, seqid, iprot, oprot):
        args = get_multi_slice_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = get_multi_slice_result()
        try:
            result.success = self._handler.get_multi_slice(args.request)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("get_multi_slice", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_schema_versions(self, seqid, iprot, oprot):
        args = describe_schema_versions_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_schema_versions_result()
        try:
            result.success = self._handler.describe_schema_versions()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_schema_versions", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_keyspaces(self, seqid, iprot, oprot):
        args = describe_keyspaces_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_keyspaces_result()
        try:
            result.success = self._handler.describe_keyspaces()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_keyspaces", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_cluster_name(self, seqid, iprot, oprot):
        args = describe_cluster_name_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_cluster_name_result()
        try:
            result.success = self._handler.describe_cluster_name()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_cluster_name", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_version(self, seqid, iprot, oprot):
        args = describe_version_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_version_result()
        try:
            result.success = self._handler.describe_version()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_version", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_ring(self, seqid, iprot, oprot):
        args = describe_ring_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_ring_result()
        try:
            result.success = self._handler.describe_ring(args.keyspace)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_ring", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_local_ring(self, seqid, iprot, oprot):
        args = describe_local_ring_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_local_ring_result()
        try:
            result.success = self._handler.describe_local_ring(args.keyspace)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_local_ring", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_token_map(self, seqid, iprot, oprot):
        args = describe_token_map_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_token_map_result()
        try:
            result.success = self._handler.describe_token_map()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_token_map", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_partitioner(self, seqid, iprot, oprot):
        args = describe_partitioner_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_partitioner_result()
        try:
            result.success = self._handler.describe_partitioner()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_partitioner", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_snitch(self, seqid, iprot, oprot):
        args = describe_snitch_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_snitch_result()
        try:
            result.success = self._handler.describe_snitch()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_snitch", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_keyspace(self, seqid, iprot, oprot):
        args = describe_keyspace_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_keyspace_result()
        try:
            result.success = self._handler.describe_keyspace(args.keyspace)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except NotFoundException as nfe:
            msg_type = TMessageType.REPLY
            result.nfe = nfe
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_keyspace", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_splits(self, seqid, iprot, oprot):
        args = describe_splits_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_splits_result()
        try:
            result.success = self._handler.describe_splits(args.cfName, args.start_token, args.end_token, args.keys_per_split)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_splits", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_trace_next_query(self, seqid, iprot, oprot):
        args = trace_next_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = trace_next_query_result()
        try:
            result.success = self._handler.trace_next_query()
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("trace_next_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_describe_splits_ex(self, seqid, iprot, oprot):
        args = describe_splits_ex_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = describe_splits_ex_result()
        try:
            result.success = self._handler.describe_splits_ex(args.cfName, args.start_token, args.end_token, args.keys_per_split)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("describe_splits_ex", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_system_add_column_family(self, seqid, iprot, oprot):
        args = system_add_column_family_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = system_add_column_family_result()
        try:
            result.success = self._handler.system_add_column_family(args.cf_def)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("system_add_column_family", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_system_drop_column_family(self, seqid, iprot, oprot):
        args = system_drop_column_family_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = system_drop_column_family_result()
        try:
            result.success = self._handler.system_drop_column_family(args.column_family)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("system_drop_column_family", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_system_add_keyspace(self, seqid, iprot, oprot):
        args = system_add_keyspace_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = system_add_keyspace_result()
        try:
            result.success = self._handler.system_add_keyspace(args.ks_def)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("system_add_keyspace", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_system_drop_keyspace(self, seqid, iprot, oprot):
        args = system_drop_keyspace_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = system_drop_keyspace_result()
        try:
            result.success = self._handler.system_drop_keyspace(args.keyspace)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("system_drop_keyspace", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_system_update_keyspace(self, seqid, iprot, oprot):
        args = system_update_keyspace_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = system_update_keyspace_result()
        try:
            result.success = self._handler.system_update_keyspace(args.ks_def)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("system_update_keyspace", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_system_update_column_family(self, seqid, iprot, oprot):
        args = system_update_column_family_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = system_update_column_family_result()
        try:
            result.success = self._handler.system_update_column_family(args.cf_def)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("system_update_column_family", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_execute_cql_query(self, seqid, iprot, oprot):
        args = execute_cql_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = execute_cql_query_result()
        try:
            result.success = self._handler.execute_cql_query(args.query, args.compression)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("execute_cql_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_execute_cql3_query(self, seqid, iprot, oprot):
        args = execute_cql3_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = execute_cql3_query_result()
        try:
            result.success = self._handler.execute_cql3_query(args.query, args.compression, args.consistency)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("execute_cql3_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_prepare_cql_query(self, seqid, iprot, oprot):
        args = prepare_cql_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = prepare_cql_query_result()
        try:
            result.success = self._handler.prepare_cql_query(args.query, args.compression)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("prepare_cql_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_prepare_cql3_query(self, seqid, iprot, oprot):
        args = prepare_cql3_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = prepare_cql3_query_result()
        try:
            result.success = self._handler.prepare_cql3_query(args.query, args.compression)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("prepare_cql3_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_execute_prepared_cql_query(self, seqid, iprot, oprot):
        args = execute_prepared_cql_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = execute_prepared_cql_query_result()
        try:
            result.success = self._handler.execute_prepared_cql_query(args.itemId, args.values)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("execute_prepared_cql_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_execute_prepared_cql3_query(self, seqid, iprot, oprot):
        args = execute_prepared_cql3_query_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = execute_prepared_cql3_query_result()
        try:
            result.success = self._handler.execute_prepared_cql3_query(args.itemId, args.values, args.consistency)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except UnavailableException as ue:
            msg_type = TMessageType.REPLY
            result.ue = ue
        except TimedOutException as te:
            msg_type = TMessageType.REPLY
            result.te = te
        except SchemaDisagreementException as sde:
            msg_type = TMessageType.REPLY
            result.sde = sde
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("execute_prepared_cql3_query", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_set_cql_version(self, seqid, iprot, oprot):
        args = set_cql_version_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = set_cql_version_result()
        try:
            self._handler.set_cql_version(args.version)
            msg_type = TMessageType.REPLY
        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
            raise
        except InvalidRequestException as ire:
            msg_type = TMessageType.REPLY
            result.ire = ire
        except Exception as ex:
            msg_type = TMessageType.EXCEPTION
            logging.exception(ex)
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("set_cql_version", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

# HELPER FUNCTIONS AND STRUCTURES


class login_args(object):
    """
    Attributes:
     - auth_request
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'auth_request', (AuthenticationRequest, AuthenticationRequest.thrift_spec), None, ),  # 1
    )

    def __init__(self, auth_request=None,):
        self.auth_request = auth_request

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.auth_request = AuthenticationRequest()
                    self.auth_request.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('login_args')
        if self.auth_request is not None:
            oprot.writeFieldBegin('auth_request', TType.STRUCT, 1)
            self.auth_request.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.auth_request is None:
            raise TProtocolException(message='Required field auth_request is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class login_result(object):
    """
    Attributes:
     - authnx
     - authzx
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'authnx', (AuthenticationException, AuthenticationException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'authzx', (AuthorizationException, AuthorizationException.thrift_spec), None, ),  # 2
    )

    def __init__(self, authnx=None, authzx=None,):
        self.authnx = authnx
        self.authzx = authzx

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authnx = AuthenticationException()
                    self.authnx.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.authzx = AuthorizationException()
                    self.authzx.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('login_result')
        if self.authnx is not None:
            oprot.writeFieldBegin('authnx', TType.STRUCT, 1)
            self.authnx.write(oprot)
            oprot.writeFieldEnd()
        if self.authzx is not None:
            oprot.writeFieldBegin('authzx', TType.STRUCT, 2)
            self.authzx.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class set_keyspace_args(object):
    """
    Attributes:
     - keyspace
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'keyspace', 'UTF8', None, ),  # 1
    )

    def __init__(self, keyspace=None,):
        self.keyspace = keyspace

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.keyspace = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('set_keyspace_args')
        if self.keyspace is not None:
            oprot.writeFieldBegin('keyspace', TType.STRING, 1)
            oprot.writeString(self.keyspace.encode('utf-8') if sys.version_info[0] == 2 else self.keyspace)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keyspace is None:
            raise TProtocolException(message='Required field keyspace is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class set_keyspace_result(object):
    """
    Attributes:
     - ire
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, ire=None,):
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('set_keyspace_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_args(object):
    """
    Attributes:
     - key
     - column_path
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'column_path', (ColumnPath, ColumnPath.thrift_spec), None, ),  # 2
        (3, TType.I32, 'consistency_level', None, 1, ),  # 3
    )

    def __init__(self, key=None, column_path=None, consistency_level=thrift_spec[3][4],):
        self.key = key
        self.column_path = column_path
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_path = ColumnPath()
                    self.column_path.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_path is not None:
            oprot.writeFieldBegin('column_path', TType.STRUCT, 2)
            self.column_path.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 3)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_path is None:
            raise TProtocolException(message='Required field column_path is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_result(object):
    """
    Attributes:
     - success
     - ire
     - nfe
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'nfe', (NotFoundException, NotFoundException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 3
        (4, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 4
    )

    def __init__(self, success=None, ire=None, nfe=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.nfe = nfe
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = ColumnOrSuperColumn()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.nfe = NotFoundException()
                    self.nfe.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.nfe is not None:
            oprot.writeFieldBegin('nfe', TType.STRUCT, 2)
            self.nfe.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 3)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 4)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_slice_args(object):
    """
    Attributes:
     - key
     - column_parent
     - predicate
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, key=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
        self.key = key
        self.column_parent = column_parent
        self.predicate = predicate
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.predicate = SlicePredicate()
                    self.predicate.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_slice_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.predicate is not None:
            oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
            self.predicate.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.predicate is None:
            raise TProtocolException(message='Required field predicate is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_slice_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype201, _size198) = iprot.readListBegin()
                    for _i202 in range(_size198):
                        _elem203 = ColumnOrSuperColumn()
                        _elem203.read(iprot)
                        self.success.append(_elem203)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_slice_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter204 in self.success:
                iter204.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_count_args(object):
    """
    Attributes:
     - key
     - column_parent
     - predicate
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, key=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
        self.key = key
        self.column_parent = column_parent
        self.predicate = predicate
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.predicate = SlicePredicate()
                    self.predicate.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_count_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.predicate is not None:
            oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
            self.predicate.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.predicate is None:
            raise TProtocolException(message='Required field predicate is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_count_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.I32, 'success', None, None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.I32:
                    self.success = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_count_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.I32, 0)
            oprot.writeI32(self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class multiget_slice_args(object):
    """
    Attributes:
     - keys
     - column_parent
     - predicate
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.LIST, 'keys', (TType.STRING, 'BINARY', False), None, ),  # 1
        (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, keys=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
        self.keys = keys
        self.column_parent = column_parent
        self.predicate = predicate
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.LIST:
                    self.keys = []
                    (_etype208, _size205) = iprot.readListBegin()
                    for _i209 in range(_size205):
                        _elem210 = iprot.readBinary()
                        self.keys.append(_elem210)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.predicate = SlicePredicate()
                    self.predicate.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('multiget_slice_args')
        if self.keys is not None:
            oprot.writeFieldBegin('keys', TType.LIST, 1)
            oprot.writeListBegin(TType.STRING, len(self.keys))
            for iter211 in self.keys:
                oprot.writeBinary(iter211)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.predicate is not None:
            oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
            self.predicate.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keys is None:
            raise TProtocolException(message='Required field keys is unset!')
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.predicate is None:
            raise TProtocolException(message='Required field predicate is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class multiget_slice_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.MAP, 'success', (TType.STRING, 'BINARY', TType.LIST, (TType.STRUCT, (ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec), False), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.MAP:
                    self.success = {}
                    (_ktype213, _vtype214, _size212) = iprot.readMapBegin()
                    for _i216 in range(_size212):
                        _key217 = iprot.readBinary()
                        _val218 = []
                        (_etype222, _size219) = iprot.readListBegin()
                        for _i223 in range(_size219):
                            _elem224 = ColumnOrSuperColumn()
                            _elem224.read(iprot)
                            _val218.append(_elem224)
                        iprot.readListEnd()
                        self.success[_key217] = _val218
                    iprot.readMapEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('multiget_slice_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.MAP, 0)
            oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.success))
            for kiter225, viter226 in self.success.items():
                oprot.writeBinary(kiter225)
                oprot.writeListBegin(TType.STRUCT, len(viter226))
                for iter227 in viter226:
                    iter227.write(oprot)
                oprot.writeListEnd()
            oprot.writeMapEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class multiget_count_args(object):
    """
    Attributes:
     - keys
     - column_parent
     - predicate
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.LIST, 'keys', (TType.STRING, 'BINARY', False), None, ),  # 1
        (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, keys=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
        self.keys = keys
        self.column_parent = column_parent
        self.predicate = predicate
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.LIST:
                    self.keys = []
                    (_etype231, _size228) = iprot.readListBegin()
                    for _i232 in range(_size228):
                        _elem233 = iprot.readBinary()
                        self.keys.append(_elem233)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.predicate = SlicePredicate()
                    self.predicate.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('multiget_count_args')
        if self.keys is not None:
            oprot.writeFieldBegin('keys', TType.LIST, 1)
            oprot.writeListBegin(TType.STRING, len(self.keys))
            for iter234 in self.keys:
                oprot.writeBinary(iter234)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.predicate is not None:
            oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
            self.predicate.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keys is None:
            raise TProtocolException(message='Required field keys is unset!')
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.predicate is None:
            raise TProtocolException(message='Required field predicate is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class multiget_count_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.MAP, 'success', (TType.STRING, 'BINARY', TType.I32, None, False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.MAP:
                    self.success = {}
                    (_ktype236, _vtype237, _size235) = iprot.readMapBegin()
                    for _i239 in range(_size235):
                        _key240 = iprot.readBinary()
                        _val241 = iprot.readI32()
                        self.success[_key240] = _val241
                    iprot.readMapEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('multiget_count_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.MAP, 0)
            oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
            for kiter242, viter243 in self.success.items():
                oprot.writeBinary(kiter242)
                oprot.writeI32(viter243)
            oprot.writeMapEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_range_slices_args(object):
    """
    Attributes:
     - column_parent
     - predicate
     - range
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'range', (KeyRange, KeyRange.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, column_parent=None, predicate=None, range=None, consistency_level=thrift_spec[4][4],):
        self.column_parent = column_parent
        self.predicate = predicate
        self.range = range
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.predicate = SlicePredicate()
                    self.predicate.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.range = KeyRange()
                    self.range.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_range_slices_args')
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 1)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.predicate is not None:
            oprot.writeFieldBegin('predicate', TType.STRUCT, 2)
            self.predicate.write(oprot)
            oprot.writeFieldEnd()
        if self.range is not None:
            oprot.writeFieldBegin('range', TType.STRUCT, 3)
            self.range.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.predicate is None:
            raise TProtocolException(message='Required field predicate is unset!')
        if self.range is None:
            raise TProtocolException(message='Required field range is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_range_slices_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (KeySlice, KeySlice.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype247, _size244) = iprot.readListBegin()
                    for _i248 in range(_size244):
                        _elem249 = KeySlice()
                        _elem249.read(iprot)
                        self.success.append(_elem249)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_range_slices_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter250 in self.success:
                iter250.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_paged_slice_args(object):
    """
    Attributes:
     - column_family
     - range
     - start_column
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'column_family', 'UTF8', None, ),  # 1
        (2, TType.STRUCT, 'range', (KeyRange, KeyRange.thrift_spec), None, ),  # 2
        (3, TType.STRING, 'start_column', 'BINARY', None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, column_family=None, range=None, start_column=None, consistency_level=thrift_spec[4][4],):
        self.column_family = column_family
        self.range = range
        self.start_column = start_column
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.column_family = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.range = KeyRange()
                    self.range.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.start_column = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_paged_slice_args')
        if self.column_family is not None:
            oprot.writeFieldBegin('column_family', TType.STRING, 1)
            oprot.writeString(self.column_family.encode('utf-8') if sys.version_info[0] == 2 else self.column_family)
            oprot.writeFieldEnd()
        if self.range is not None:
            oprot.writeFieldBegin('range', TType.STRUCT, 2)
            self.range.write(oprot)
            oprot.writeFieldEnd()
        if self.start_column is not None:
            oprot.writeFieldBegin('start_column', TType.STRING, 3)
            oprot.writeBinary(self.start_column)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.column_family is None:
            raise TProtocolException(message='Required field column_family is unset!')
        if self.range is None:
            raise TProtocolException(message='Required field range is unset!')
        if self.start_column is None:
            raise TProtocolException(message='Required field start_column is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_paged_slice_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (KeySlice, KeySlice.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype254, _size251) = iprot.readListBegin()
                    for _i255 in range(_size251):
                        _elem256 = KeySlice()
                        _elem256.read(iprot)
                        self.success.append(_elem256)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_paged_slice_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter257 in self.success:
                iter257.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_indexed_slices_args(object):
    """
    Attributes:
     - column_parent
     - index_clause
     - column_predicate
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'index_clause', (IndexClause, IndexClause.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'column_predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, column_parent=None, index_clause=None, column_predicate=None, consistency_level=thrift_spec[4][4],):
        self.column_parent = column_parent
        self.index_clause = index_clause
        self.column_predicate = column_predicate
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.index_clause = IndexClause()
                    self.index_clause.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.column_predicate = SlicePredicate()
                    self.column_predicate.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_indexed_slices_args')
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 1)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.index_clause is not None:
            oprot.writeFieldBegin('index_clause', TType.STRUCT, 2)
            self.index_clause.write(oprot)
            oprot.writeFieldEnd()
        if self.column_predicate is not None:
            oprot.writeFieldBegin('column_predicate', TType.STRUCT, 3)
            self.column_predicate.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.index_clause is None:
            raise TProtocolException(message='Required field index_clause is unset!')
        if self.column_predicate is None:
            raise TProtocolException(message='Required field column_predicate is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_indexed_slices_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (KeySlice, KeySlice.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype261, _size258) = iprot.readListBegin()
                    for _i262 in range(_size258):
                        _elem263 = KeySlice()
                        _elem263.read(iprot)
                        self.success.append(_elem263)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_indexed_slices_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter264 in self.success:
                iter264.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class insert_args(object):
    """
    Attributes:
     - key
     - column_parent
     - column
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'column', (Column, Column.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, key=None, column_parent=None, column=None, consistency_level=thrift_spec[4][4],):
        self.key = key
        self.column_parent = column_parent
        self.column = column
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.column = Column()
                    self.column.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('insert_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.column is not None:
            oprot.writeFieldBegin('column', TType.STRUCT, 3)
            self.column.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.column is None:
            raise TProtocolException(message='Required field column is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class insert_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('insert_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class add_args(object):
    """
    Attributes:
     - key
     - column_parent
     - column
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'column', (CounterColumn, CounterColumn.thrift_spec), None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, key=None, column_parent=None, column=None, consistency_level=thrift_spec[4][4],):
        self.key = key
        self.column_parent = column_parent
        self.column = column
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_parent = ColumnParent()
                    self.column_parent.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.column = CounterColumn()
                    self.column.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('add_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_parent is not None:
            oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
            self.column_parent.write(oprot)
            oprot.writeFieldEnd()
        if self.column is not None:
            oprot.writeFieldBegin('column', TType.STRUCT, 3)
            self.column.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_parent is None:
            raise TProtocolException(message='Required field column_parent is unset!')
        if self.column is None:
            raise TProtocolException(message='Required field column is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class add_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('add_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class cas_args(object):
    """
    Attributes:
     - key
     - column_family
     - expected
     - updates
     - serial_consistency_level
     - commit_consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRING, 'column_family', 'UTF8', None, ),  # 2
        (3, TType.LIST, 'expected', (TType.STRUCT, (Column, Column.thrift_spec), False), None, ),  # 3
        (4, TType.LIST, 'updates', (TType.STRUCT, (Column, Column.thrift_spec), False), None, ),  # 4
        (5, TType.I32, 'serial_consistency_level', None, 9, ),  # 5
        (6, TType.I32, 'commit_consistency_level', None, 2, ),  # 6
    )

    def __init__(self, key=None, column_family=None, expected=None, updates=None, serial_consistency_level=thrift_spec[5][4], commit_consistency_level=thrift_spec[6][4],):
        self.key = key
        self.column_family = column_family
        self.expected = expected
        self.updates = updates
        self.serial_consistency_level = serial_consistency_level
        self.commit_consistency_level = commit_consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.column_family = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.LIST:
                    self.expected = []
                    (_etype268, _size265) = iprot.readListBegin()
                    for _i269 in range(_size265):
                        _elem270 = Column()
                        _elem270.read(iprot)
                        self.expected.append(_elem270)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.LIST:
                    self.updates = []
                    (_etype274, _size271) = iprot.readListBegin()
                    for _i275 in range(_size271):
                        _elem276 = Column()
                        _elem276.read(iprot)
                        self.updates.append(_elem276)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 5:
                if ftype == TType.I32:
                    self.serial_consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 6:
                if ftype == TType.I32:
                    self.commit_consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('cas_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_family is not None:
            oprot.writeFieldBegin('column_family', TType.STRING, 2)
            oprot.writeString(self.column_family.encode('utf-8') if sys.version_info[0] == 2 else self.column_family)
            oprot.writeFieldEnd()
        if self.expected is not None:
            oprot.writeFieldBegin('expected', TType.LIST, 3)
            oprot.writeListBegin(TType.STRUCT, len(self.expected))
            for iter277 in self.expected:
                iter277.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.updates is not None:
            oprot.writeFieldBegin('updates', TType.LIST, 4)
            oprot.writeListBegin(TType.STRUCT, len(self.updates))
            for iter278 in self.updates:
                iter278.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.serial_consistency_level is not None:
            oprot.writeFieldBegin('serial_consistency_level', TType.I32, 5)
            oprot.writeI32(self.serial_consistency_level)
            oprot.writeFieldEnd()
        if self.commit_consistency_level is not None:
            oprot.writeFieldBegin('commit_consistency_level', TType.I32, 6)
            oprot.writeI32(self.commit_consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_family is None:
            raise TProtocolException(message='Required field column_family is unset!')
        if self.serial_consistency_level is None:
            raise TProtocolException(message='Required field serial_consistency_level is unset!')
        if self.commit_consistency_level is None:
            raise TProtocolException(message='Required field commit_consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class cas_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CASResult, CASResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CASResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('cas_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class remove_args(object):
    """
    Attributes:
     - key
     - column_path
     - timestamp
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'column_path', (ColumnPath, ColumnPath.thrift_spec), None, ),  # 2
        (3, TType.I64, 'timestamp', None, None, ),  # 3
        (4, TType.I32, 'consistency_level', None, 1, ),  # 4
    )

    def __init__(self, key=None, column_path=None, timestamp=None, consistency_level=thrift_spec[4][4],):
        self.key = key
        self.column_path = column_path
        self.timestamp = timestamp
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.column_path = ColumnPath()
                    self.column_path.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I64:
                    self.timestamp = iprot.readI64()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('remove_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.column_path is not None:
            oprot.writeFieldBegin('column_path', TType.STRUCT, 2)
            self.column_path.write(oprot)
            oprot.writeFieldEnd()
        if self.timestamp is not None:
            oprot.writeFieldBegin('timestamp', TType.I64, 3)
            oprot.writeI64(self.timestamp)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 4)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.column_path is None:
            raise TProtocolException(message='Required field column_path is unset!')
        if self.timestamp is None:
            raise TProtocolException(message='Required field timestamp is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class remove_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('remove_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class remove_counter_args(object):
    """
    Attributes:
     - key
     - path
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'key', 'BINARY', None, ),  # 1
        (2, TType.STRUCT, 'path', (ColumnPath, ColumnPath.thrift_spec), None, ),  # 2
        (3, TType.I32, 'consistency_level', None, 1, ),  # 3
    )

    def __init__(self, key=None, path=None, consistency_level=thrift_spec[3][4],):
        self.key = key
        self.path = path
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.key = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.path = ColumnPath()
                    self.path.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('remove_counter_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeBinary(self.key)
            oprot.writeFieldEnd()
        if self.path is not None:
            oprot.writeFieldBegin('path', TType.STRUCT, 2)
            self.path.write(oprot)
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 3)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.key is None:
            raise TProtocolException(message='Required field key is unset!')
        if self.path is None:
            raise TProtocolException(message='Required field path is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class remove_counter_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('remove_counter_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class batch_mutate_args(object):
    """
    Attributes:
     - mutation_map
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.MAP, 'mutation_map', (TType.STRING, 'BINARY', TType.MAP, (TType.STRING, 'UTF8', TType.LIST, (TType.STRUCT, (Mutation, Mutation.thrift_spec), False), False), False), None, ),  # 1
        (2, TType.I32, 'consistency_level', None, 1, ),  # 2
    )

    def __init__(self, mutation_map=None, consistency_level=thrift_spec[2][4],):
        self.mutation_map = mutation_map
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.MAP:
                    self.mutation_map = {}
                    (_ktype280, _vtype281, _size279) = iprot.readMapBegin()
                    for _i283 in range(_size279):
                        _key284 = iprot.readBinary()
                        _val285 = {}
                        (_ktype287, _vtype288, _size286) = iprot.readMapBegin()
                        for _i290 in range(_size286):
                            _key291 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                            _val292 = []
                            (_etype296, _size293) = iprot.readListBegin()
                            for _i297 in range(_size293):
                                _elem298 = Mutation()
                                _elem298.read(iprot)
                                _val292.append(_elem298)
                            iprot.readListEnd()
                            _val285[_key291] = _val292
                        iprot.readMapEnd()
                        self.mutation_map[_key284] = _val285
                    iprot.readMapEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('batch_mutate_args')
        if self.mutation_map is not None:
            oprot.writeFieldBegin('mutation_map', TType.MAP, 1)
            oprot.writeMapBegin(TType.STRING, TType.MAP, len(self.mutation_map))
            for kiter299, viter300 in self.mutation_map.items():
                oprot.writeBinary(kiter299)
                oprot.writeMapBegin(TType.STRING, TType.LIST, len(viter300))
                for kiter301, viter302 in viter300.items():
                    oprot.writeString(kiter301.encode('utf-8') if sys.version_info[0] == 2 else kiter301)
                    oprot.writeListBegin(TType.STRUCT, len(viter302))
                    for iter303 in viter302:
                        iter303.write(oprot)
                    oprot.writeListEnd()
                oprot.writeMapEnd()
            oprot.writeMapEnd()
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 2)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.mutation_map is None:
            raise TProtocolException(message='Required field mutation_map is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class batch_mutate_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('batch_mutate_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class atomic_batch_mutate_args(object):
    """
    Attributes:
     - mutation_map
     - consistency_level
    """

    thrift_spec = (
        None,  # 0
        (1, TType.MAP, 'mutation_map', (TType.STRING, 'BINARY', TType.MAP, (TType.STRING, 'UTF8', TType.LIST, (TType.STRUCT, (Mutation, Mutation.thrift_spec), False), False), False), None, ),  # 1
        (2, TType.I32, 'consistency_level', None, 1, ),  # 2
    )

    def __init__(self, mutation_map=None, consistency_level=thrift_spec[2][4],):
        self.mutation_map = mutation_map
        self.consistency_level = consistency_level

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.MAP:
                    self.mutation_map = {}
                    (_ktype305, _vtype306, _size304) = iprot.readMapBegin()
                    for _i308 in range(_size304):
                        _key309 = iprot.readBinary()
                        _val310 = {}
                        (_ktype312, _vtype313, _size311) = iprot.readMapBegin()
                        for _i315 in range(_size311):
                            _key316 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                            _val317 = []
                            (_etype321, _size318) = iprot.readListBegin()
                            for _i322 in range(_size318):
                                _elem323 = Mutation()
                                _elem323.read(iprot)
                                _val317.append(_elem323)
                            iprot.readListEnd()
                            _val310[_key316] = _val317
                        iprot.readMapEnd()
                        self.mutation_map[_key309] = _val310
                    iprot.readMapEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.consistency_level = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('atomic_batch_mutate_args')
        if self.mutation_map is not None:
            oprot.writeFieldBegin('mutation_map', TType.MAP, 1)
            oprot.writeMapBegin(TType.STRING, TType.MAP, len(self.mutation_map))
            for kiter324, viter325 in self.mutation_map.items():
                oprot.writeBinary(kiter324)
                oprot.writeMapBegin(TType.STRING, TType.LIST, len(viter325))
                for kiter326, viter327 in viter325.items():
                    oprot.writeString(kiter326.encode('utf-8') if sys.version_info[0] == 2 else kiter326)
                    oprot.writeListBegin(TType.STRUCT, len(viter327))
                    for iter328 in viter327:
                        iter328.write(oprot)
                    oprot.writeListEnd()
                oprot.writeMapEnd()
            oprot.writeMapEnd()
            oprot.writeFieldEnd()
        if self.consistency_level is not None:
            oprot.writeFieldBegin('consistency_level', TType.I32, 2)
            oprot.writeI32(self.consistency_level)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.mutation_map is None:
            raise TProtocolException(message='Required field mutation_map is unset!')
        if self.consistency_level is None:
            raise TProtocolException(message='Required field consistency_level is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class atomic_batch_mutate_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('atomic_batch_mutate_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class truncate_args(object):
    """
    Attributes:
     - cfname
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'cfname', 'UTF8', None, ),  # 1
    )

    def __init__(self, cfname=None,):
        self.cfname = cfname

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.cfname = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('truncate_args')
        if self.cfname is not None:
            oprot.writeFieldBegin('cfname', TType.STRING, 1)
            oprot.writeString(self.cfname.encode('utf-8') if sys.version_info[0] == 2 else self.cfname)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.cfname is None:
            raise TProtocolException(message='Required field cfname is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class truncate_result(object):
    """
    Attributes:
     - ire
     - ue
     - te
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, ire=None, ue=None, te=None,):
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('truncate_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_multi_slice_args(object):
    """
    Attributes:
     - request
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'request', (MultiSliceRequest, MultiSliceRequest.thrift_spec), None, ),  # 1
    )

    def __init__(self, request=None,):
        self.request = request

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.request = MultiSliceRequest()
                    self.request.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_multi_slice_args')
        if self.request is not None:
            oprot.writeFieldBegin('request', TType.STRUCT, 1)
            self.request.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.request is None:
            raise TProtocolException(message='Required field request is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class get_multi_slice_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
    )

    def __init__(self, success=None, ire=None, ue=None, te=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype332, _size329) = iprot.readListBegin()
                    for _i333 in range(_size329):
                        _elem334 = ColumnOrSuperColumn()
                        _elem334.read(iprot)
                        self.success.append(_elem334)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('get_multi_slice_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter335 in self.success:
                iter335.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_schema_versions_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_schema_versions_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_schema_versions_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.LIST, (TType.STRING, 'UTF8', False), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.MAP:
                    self.success = {}
                    (_ktype337, _vtype338, _size336) = iprot.readMapBegin()
                    for _i340 in range(_size336):
                        _key341 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                        _val342 = []
                        (_etype346, _size343) = iprot.readListBegin()
                        for _i347 in range(_size343):
                            _elem348 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                            _val342.append(_elem348)
                        iprot.readListEnd()
                        self.success[_key341] = _val342
                    iprot.readMapEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_schema_versions_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.MAP, 0)
            oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.success))
            for kiter349, viter350 in self.success.items():
                oprot.writeString(kiter349.encode('utf-8') if sys.version_info[0] == 2 else kiter349)
                oprot.writeListBegin(TType.STRING, len(viter350))
                for iter351 in viter350:
                    oprot.writeString(iter351.encode('utf-8') if sys.version_info[0] == 2 else iter351)
                oprot.writeListEnd()
            oprot.writeMapEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_keyspaces_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_keyspaces_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_keyspaces_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (KsDef, KsDef.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype355, _size352) = iprot.readListBegin()
                    for _i356 in range(_size352):
                        _elem357 = KsDef()
                        _elem357.read(iprot)
                        self.success.append(_elem357)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_keyspaces_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter358 in self.success:
                iter358.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_cluster_name_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_cluster_name_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_cluster_name_result(object):
    """
    Attributes:
     - success
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    )

    def __init__(self, success=None,):
        self.success = success

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_cluster_name_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_version_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_version_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_version_result(object):
    """
    Attributes:
     - success
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    )

    def __init__(self, success=None,):
        self.success = success

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_version_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_ring_args(object):
    """
    Attributes:
     - keyspace
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'keyspace', 'UTF8', None, ),  # 1
    )

    def __init__(self, keyspace=None,):
        self.keyspace = keyspace

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.keyspace = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_ring_args')
        if self.keyspace is not None:
            oprot.writeFieldBegin('keyspace', TType.STRING, 1)
            oprot.writeString(self.keyspace.encode('utf-8') if sys.version_info[0] == 2 else self.keyspace)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keyspace is None:
            raise TProtocolException(message='Required field keyspace is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_ring_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (TokenRange, TokenRange.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype362, _size359) = iprot.readListBegin()
                    for _i363 in range(_size359):
                        _elem364 = TokenRange()
                        _elem364.read(iprot)
                        self.success.append(_elem364)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_ring_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter365 in self.success:
                iter365.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_local_ring_args(object):
    """
    Attributes:
     - keyspace
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'keyspace', 'UTF8', None, ),  # 1
    )

    def __init__(self, keyspace=None,):
        self.keyspace = keyspace

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.keyspace = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_local_ring_args')
        if self.keyspace is not None:
            oprot.writeFieldBegin('keyspace', TType.STRING, 1)
            oprot.writeString(self.keyspace.encode('utf-8') if sys.version_info[0] == 2 else self.keyspace)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keyspace is None:
            raise TProtocolException(message='Required field keyspace is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_local_ring_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (TokenRange, TokenRange.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype369, _size366) = iprot.readListBegin()
                    for _i370 in range(_size366):
                        _elem371 = TokenRange()
                        _elem371.read(iprot)
                        self.success.append(_elem371)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_local_ring_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter372 in self.success:
                iter372.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_token_map_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_token_map_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_token_map_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.MAP:
                    self.success = {}
                    (_ktype374, _vtype375, _size373) = iprot.readMapBegin()
                    for _i377 in range(_size373):
                        _key378 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                        _val379 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                        self.success[_key378] = _val379
                    iprot.readMapEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_token_map_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.MAP, 0)
            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
            for kiter380, viter381 in self.success.items():
                oprot.writeString(kiter380.encode('utf-8') if sys.version_info[0] == 2 else kiter380)
                oprot.writeString(viter381.encode('utf-8') if sys.version_info[0] == 2 else viter381)
            oprot.writeMapEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_partitioner_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_partitioner_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_partitioner_result(object):
    """
    Attributes:
     - success
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    )

    def __init__(self, success=None,):
        self.success = success

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_partitioner_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_snitch_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_snitch_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_snitch_result(object):
    """
    Attributes:
     - success
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    )

    def __init__(self, success=None,):
        self.success = success

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_snitch_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_keyspace_args(object):
    """
    Attributes:
     - keyspace
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'keyspace', 'UTF8', None, ),  # 1
    )

    def __init__(self, keyspace=None,):
        self.keyspace = keyspace

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.keyspace = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_keyspace_args')
        if self.keyspace is not None:
            oprot.writeFieldBegin('keyspace', TType.STRING, 1)
            oprot.writeString(self.keyspace.encode('utf-8') if sys.version_info[0] == 2 else self.keyspace)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keyspace is None:
            raise TProtocolException(message='Required field keyspace is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_keyspace_result(object):
    """
    Attributes:
     - success
     - nfe
     - ire
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (KsDef, KsDef.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'nfe', (NotFoundException, NotFoundException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, nfe=None, ire=None,):
        self.success = success
        self.nfe = nfe
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = KsDef()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.nfe = NotFoundException()
                    self.nfe.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_keyspace_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.nfe is not None:
            oprot.writeFieldBegin('nfe', TType.STRUCT, 1)
            self.nfe.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 2)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_splits_args(object):
    """
    Attributes:
     - cfName
     - start_token
     - end_token
     - keys_per_split
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'cfName', 'UTF8', None, ),  # 1
        (2, TType.STRING, 'start_token', 'UTF8', None, ),  # 2
        (3, TType.STRING, 'end_token', 'UTF8', None, ),  # 3
        (4, TType.I32, 'keys_per_split', None, None, ),  # 4
    )

    def __init__(self, cfName=None, start_token=None, end_token=None, keys_per_split=None,):
        self.cfName = cfName
        self.start_token = start_token
        self.end_token = end_token
        self.keys_per_split = keys_per_split

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.cfName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.start_token = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.end_token = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.keys_per_split = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_splits_args')
        if self.cfName is not None:
            oprot.writeFieldBegin('cfName', TType.STRING, 1)
            oprot.writeString(self.cfName.encode('utf-8') if sys.version_info[0] == 2 else self.cfName)
            oprot.writeFieldEnd()
        if self.start_token is not None:
            oprot.writeFieldBegin('start_token', TType.STRING, 2)
            oprot.writeString(self.start_token.encode('utf-8') if sys.version_info[0] == 2 else self.start_token)
            oprot.writeFieldEnd()
        if self.end_token is not None:
            oprot.writeFieldBegin('end_token', TType.STRING, 3)
            oprot.writeString(self.end_token.encode('utf-8') if sys.version_info[0] == 2 else self.end_token)
            oprot.writeFieldEnd()
        if self.keys_per_split is not None:
            oprot.writeFieldBegin('keys_per_split', TType.I32, 4)
            oprot.writeI32(self.keys_per_split)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.cfName is None:
            raise TProtocolException(message='Required field cfName is unset!')
        if self.start_token is None:
            raise TProtocolException(message='Required field start_token is unset!')
        if self.end_token is None:
            raise TProtocolException(message='Required field end_token is unset!')
        if self.keys_per_split is None:
            raise TProtocolException(message='Required field keys_per_split is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_splits_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRING, 'UTF8', False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype385, _size382) = iprot.readListBegin()
                    for _i386 in range(_size382):
                        _elem387 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                        self.success.append(_elem387)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_splits_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRING, len(self.success))
            for iter388 in self.success:
                oprot.writeString(iter388.encode('utf-8') if sys.version_info[0] == 2 else iter388)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class trace_next_query_args(object):

    thrift_spec = (
    )

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('trace_next_query_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class trace_next_query_result(object):
    """
    Attributes:
     - success
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'BINARY', None, ),  # 0
    )

    def __init__(self, success=None,):
        self.success = success

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('trace_next_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeBinary(self.success)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_splits_ex_args(object):
    """
    Attributes:
     - cfName
     - start_token
     - end_token
     - keys_per_split
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'cfName', 'UTF8', None, ),  # 1
        (2, TType.STRING, 'start_token', 'UTF8', None, ),  # 2
        (3, TType.STRING, 'end_token', 'UTF8', None, ),  # 3
        (4, TType.I32, 'keys_per_split', None, None, ),  # 4
    )

    def __init__(self, cfName=None, start_token=None, end_token=None, keys_per_split=None,):
        self.cfName = cfName
        self.start_token = start_token
        self.end_token = end_token
        self.keys_per_split = keys_per_split

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.cfName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.start_token = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.end_token = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.keys_per_split = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_splits_ex_args')
        if self.cfName is not None:
            oprot.writeFieldBegin('cfName', TType.STRING, 1)
            oprot.writeString(self.cfName.encode('utf-8') if sys.version_info[0] == 2 else self.cfName)
            oprot.writeFieldEnd()
        if self.start_token is not None:
            oprot.writeFieldBegin('start_token', TType.STRING, 2)
            oprot.writeString(self.start_token.encode('utf-8') if sys.version_info[0] == 2 else self.start_token)
            oprot.writeFieldEnd()
        if self.end_token is not None:
            oprot.writeFieldBegin('end_token', TType.STRING, 3)
            oprot.writeString(self.end_token.encode('utf-8') if sys.version_info[0] == 2 else self.end_token)
            oprot.writeFieldEnd()
        if self.keys_per_split is not None:
            oprot.writeFieldBegin('keys_per_split', TType.I32, 4)
            oprot.writeI32(self.keys_per_split)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.cfName is None:
            raise TProtocolException(message='Required field cfName is unset!')
        if self.start_token is None:
            raise TProtocolException(message='Required field start_token is unset!')
        if self.end_token is None:
            raise TProtocolException(message='Required field end_token is unset!')
        if self.keys_per_split is None:
            raise TProtocolException(message='Required field keys_per_split is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class describe_splits_ex_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.LIST, 'success', (TType.STRUCT, (CfSplit, CfSplit.thrift_spec), False), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype392, _size389) = iprot.readListBegin()
                    for _i393 in range(_size389):
                        _elem394 = CfSplit()
                        _elem394.read(iprot)
                        self.success.append(_elem394)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('describe_splits_ex_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter395 in self.success:
                iter395.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_add_column_family_args(object):
    """
    Attributes:
     - cf_def
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'cf_def', (CfDef, CfDef.thrift_spec), None, ),  # 1
    )

    def __init__(self, cf_def=None,):
        self.cf_def = cf_def

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.cf_def = CfDef()
                    self.cf_def.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_add_column_family_args')
        if self.cf_def is not None:
            oprot.writeFieldBegin('cf_def', TType.STRUCT, 1)
            self.cf_def.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.cf_def is None:
            raise TProtocolException(message='Required field cf_def is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_add_column_family_result(object):
    """
    Attributes:
     - success
     - ire
     - sde
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, ire=None, sde=None,):
        self.success = success
        self.ire = ire
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_add_column_family_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 2)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_drop_column_family_args(object):
    """
    Attributes:
     - column_family
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'column_family', 'UTF8', None, ),  # 1
    )

    def __init__(self, column_family=None,):
        self.column_family = column_family

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.column_family = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_drop_column_family_args')
        if self.column_family is not None:
            oprot.writeFieldBegin('column_family', TType.STRING, 1)
            oprot.writeString(self.column_family.encode('utf-8') if sys.version_info[0] == 2 else self.column_family)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.column_family is None:
            raise TProtocolException(message='Required field column_family is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_drop_column_family_result(object):
    """
    Attributes:
     - success
     - ire
     - sde
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, ire=None, sde=None,):
        self.success = success
        self.ire = ire
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_drop_column_family_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 2)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_add_keyspace_args(object):
    """
    Attributes:
     - ks_def
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ks_def', (KsDef, KsDef.thrift_spec), None, ),  # 1
    )

    def __init__(self, ks_def=None,):
        self.ks_def = ks_def

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ks_def = KsDef()
                    self.ks_def.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_add_keyspace_args')
        if self.ks_def is not None:
            oprot.writeFieldBegin('ks_def', TType.STRUCT, 1)
            self.ks_def.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.ks_def is None:
            raise TProtocolException(message='Required field ks_def is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_add_keyspace_result(object):
    """
    Attributes:
     - success
     - ire
     - sde
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, ire=None, sde=None,):
        self.success = success
        self.ire = ire
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_add_keyspace_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 2)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_drop_keyspace_args(object):
    """
    Attributes:
     - keyspace
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'keyspace', 'UTF8', None, ),  # 1
    )

    def __init__(self, keyspace=None,):
        self.keyspace = keyspace

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.keyspace = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_drop_keyspace_args')
        if self.keyspace is not None:
            oprot.writeFieldBegin('keyspace', TType.STRING, 1)
            oprot.writeString(self.keyspace.encode('utf-8') if sys.version_info[0] == 2 else self.keyspace)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.keyspace is None:
            raise TProtocolException(message='Required field keyspace is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_drop_keyspace_result(object):
    """
    Attributes:
     - success
     - ire
     - sde
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, ire=None, sde=None,):
        self.success = success
        self.ire = ire
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_drop_keyspace_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 2)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_update_keyspace_args(object):
    """
    Attributes:
     - ks_def
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ks_def', (KsDef, KsDef.thrift_spec), None, ),  # 1
    )

    def __init__(self, ks_def=None,):
        self.ks_def = ks_def

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ks_def = KsDef()
                    self.ks_def.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_update_keyspace_args')
        if self.ks_def is not None:
            oprot.writeFieldBegin('ks_def', TType.STRUCT, 1)
            self.ks_def.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.ks_def is None:
            raise TProtocolException(message='Required field ks_def is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_update_keyspace_result(object):
    """
    Attributes:
     - success
     - ire
     - sde
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, ire=None, sde=None,):
        self.success = success
        self.ire = ire
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_update_keyspace_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 2)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_update_column_family_args(object):
    """
    Attributes:
     - cf_def
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'cf_def', (CfDef, CfDef.thrift_spec), None, ),  # 1
    )

    def __init__(self, cf_def=None,):
        self.cf_def = cf_def

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.cf_def = CfDef()
                    self.cf_def.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_update_column_family_args')
        if self.cf_def is not None:
            oprot.writeFieldBegin('cf_def', TType.STRUCT, 1)
            self.cf_def.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.cf_def is None:
            raise TProtocolException(message='Required field cf_def is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class system_update_column_family_result(object):
    """
    Attributes:
     - success
     - ire
     - sde
    """

    thrift_spec = (
        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 2
    )

    def __init__(self, success=None, ire=None, sde=None,):
        self.success = success
        self.ire = ire
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRING:
                    self.success = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('system_update_column_family_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 2)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_cql_query_args(object):
    """
    Attributes:
     - query
     - compression
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'query', 'BINARY', None, ),  # 1
        (2, TType.I32, 'compression', None, None, ),  # 2
    )

    def __init__(self, query=None, compression=None,):
        self.query = query
        self.compression = compression

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.query = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.compression = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_cql_query_args')
        if self.query is not None:
            oprot.writeFieldBegin('query', TType.STRING, 1)
            oprot.writeBinary(self.query)
            oprot.writeFieldEnd()
        if self.compression is not None:
            oprot.writeFieldBegin('compression', TType.I32, 2)
            oprot.writeI32(self.compression)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.query is None:
            raise TProtocolException(message='Required field query is unset!')
        if self.compression is None:
            raise TProtocolException(message='Required field compression is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_cql_query_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
     - sde
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CqlResult, CqlResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
        (4, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 4
    )

    def __init__(self, success=None, ire=None, ue=None, te=None, sde=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CqlResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_cql_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 4)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_cql3_query_args(object):
    """
    Attributes:
     - query
     - compression
     - consistency
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'query', 'BINARY', None, ),  # 1
        (2, TType.I32, 'compression', None, None, ),  # 2
        (3, TType.I32, 'consistency', None, None, ),  # 3
    )

    def __init__(self, query=None, compression=None, consistency=None,):
        self.query = query
        self.compression = compression
        self.consistency = consistency

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.query = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.compression = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.consistency = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_cql3_query_args')
        if self.query is not None:
            oprot.writeFieldBegin('query', TType.STRING, 1)
            oprot.writeBinary(self.query)
            oprot.writeFieldEnd()
        if self.compression is not None:
            oprot.writeFieldBegin('compression', TType.I32, 2)
            oprot.writeI32(self.compression)
            oprot.writeFieldEnd()
        if self.consistency is not None:
            oprot.writeFieldBegin('consistency', TType.I32, 3)
            oprot.writeI32(self.consistency)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.query is None:
            raise TProtocolException(message='Required field query is unset!')
        if self.compression is None:
            raise TProtocolException(message='Required field compression is unset!')
        if self.consistency is None:
            raise TProtocolException(message='Required field consistency is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_cql3_query_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
     - sde
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CqlResult, CqlResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
        (4, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 4
    )

    def __init__(self, success=None, ire=None, ue=None, te=None, sde=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CqlResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_cql3_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 4)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class prepare_cql_query_args(object):
    """
    Attributes:
     - query
     - compression
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'query', 'BINARY', None, ),  # 1
        (2, TType.I32, 'compression', None, None, ),  # 2
    )

    def __init__(self, query=None, compression=None,):
        self.query = query
        self.compression = compression

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.query = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.compression = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('prepare_cql_query_args')
        if self.query is not None:
            oprot.writeFieldBegin('query', TType.STRING, 1)
            oprot.writeBinary(self.query)
            oprot.writeFieldEnd()
        if self.compression is not None:
            oprot.writeFieldBegin('compression', TType.I32, 2)
            oprot.writeI32(self.compression)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.query is None:
            raise TProtocolException(message='Required field query is unset!')
        if self.compression is None:
            raise TProtocolException(message='Required field compression is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class prepare_cql_query_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CqlPreparedResult, CqlPreparedResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CqlPreparedResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('prepare_cql_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class prepare_cql3_query_args(object):
    """
    Attributes:
     - query
     - compression
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'query', 'BINARY', None, ),  # 1
        (2, TType.I32, 'compression', None, None, ),  # 2
    )

    def __init__(self, query=None, compression=None,):
        self.query = query
        self.compression = compression

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.query = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.compression = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('prepare_cql3_query_args')
        if self.query is not None:
            oprot.writeFieldBegin('query', TType.STRING, 1)
            oprot.writeBinary(self.query)
            oprot.writeFieldEnd()
        if self.compression is not None:
            oprot.writeFieldBegin('compression', TType.I32, 2)
            oprot.writeI32(self.compression)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.query is None:
            raise TProtocolException(message='Required field query is unset!')
        if self.compression is None:
            raise TProtocolException(message='Required field compression is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class prepare_cql3_query_result(object):
    """
    Attributes:
     - success
     - ire
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CqlPreparedResult, CqlPreparedResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, success=None, ire=None,):
        self.success = success
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CqlPreparedResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('prepare_cql3_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_prepared_cql_query_args(object):
    """
    Attributes:
     - itemId
     - values
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'itemId', None, None, ),  # 1
        (2, TType.LIST, 'values', (TType.STRING, 'BINARY', False), None, ),  # 2
    )

    def __init__(self, itemId=None, values=None,):
        self.itemId = itemId
        self.values = values

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.I32:
                    self.itemId = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.LIST:
                    self.values = []
                    (_etype399, _size396) = iprot.readListBegin()
                    for _i400 in range(_size396):
                        _elem401 = iprot.readBinary()
                        self.values.append(_elem401)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_prepared_cql_query_args')
        if self.itemId is not None:
            oprot.writeFieldBegin('itemId', TType.I32, 1)
            oprot.writeI32(self.itemId)
            oprot.writeFieldEnd()
        if self.values is not None:
            oprot.writeFieldBegin('values', TType.LIST, 2)
            oprot.writeListBegin(TType.STRING, len(self.values))
            for iter402 in self.values:
                oprot.writeBinary(iter402)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.itemId is None:
            raise TProtocolException(message='Required field itemId is unset!')
        if self.values is None:
            raise TProtocolException(message='Required field values is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_prepared_cql_query_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
     - sde
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CqlResult, CqlResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
        (4, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 4
    )

    def __init__(self, success=None, ire=None, ue=None, te=None, sde=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CqlResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_prepared_cql_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 4)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_prepared_cql3_query_args(object):
    """
    Attributes:
     - itemId
     - values
     - consistency
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'itemId', None, None, ),  # 1
        (2, TType.LIST, 'values', (TType.STRING, 'BINARY', False), None, ),  # 2
        (3, TType.I32, 'consistency', None, None, ),  # 3
    )

    def __init__(self, itemId=None, values=None, consistency=None,):
        self.itemId = itemId
        self.values = values
        self.consistency = consistency

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.I32:
                    self.itemId = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.LIST:
                    self.values = []
                    (_etype406, _size403) = iprot.readListBegin()
                    for _i407 in range(_size403):
                        _elem408 = iprot.readBinary()
                        self.values.append(_elem408)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.consistency = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_prepared_cql3_query_args')
        if self.itemId is not None:
            oprot.writeFieldBegin('itemId', TType.I32, 1)
            oprot.writeI32(self.itemId)
            oprot.writeFieldEnd()
        if self.values is not None:
            oprot.writeFieldBegin('values', TType.LIST, 2)
            oprot.writeListBegin(TType.STRING, len(self.values))
            for iter409 in self.values:
                oprot.writeBinary(iter409)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.consistency is not None:
            oprot.writeFieldBegin('consistency', TType.I32, 3)
            oprot.writeI32(self.consistency)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.itemId is None:
            raise TProtocolException(message='Required field itemId is unset!')
        if self.values is None:
            raise TProtocolException(message='Required field values is unset!')
        if self.consistency is None:
            raise TProtocolException(message='Required field consistency is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class execute_prepared_cql3_query_result(object):
    """
    Attributes:
     - success
     - ire
     - ue
     - te
     - sde
    """

    thrift_spec = (
        (0, TType.STRUCT, 'success', (CqlResult, CqlResult.thrift_spec), None, ),  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
        (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ),  # 2
        (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ),  # 3
        (4, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ),  # 4
    )

    def __init__(self, success=None, ire=None, ue=None, te=None, sde=None,):
        self.success = success
        self.ire = ire
        self.ue = ue
        self.te = te
        self.sde = sde

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = CqlResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ue = UnavailableException()
                    self.ue.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.te = TimedOutException()
                    self.te.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRUCT:
                    self.sde = SchemaDisagreementException()
                    self.sde.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('execute_prepared_cql3_query_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        if self.ue is not None:
            oprot.writeFieldBegin('ue', TType.STRUCT, 2)
            self.ue.write(oprot)
            oprot.writeFieldEnd()
        if self.te is not None:
            oprot.writeFieldBegin('te', TType.STRUCT, 3)
            self.te.write(oprot)
            oprot.writeFieldEnd()
        if self.sde is not None:
            oprot.writeFieldBegin('sde', TType.STRUCT, 4)
            self.sde.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class set_cql_version_args(object):
    """
    Attributes:
     - version
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'version', 'UTF8', None, ),  # 1
    )

    def __init__(self, version=None,):
        self.version = version

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.version = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('set_cql_version_args')
        if self.version is not None:
            oprot.writeFieldBegin('version', TType.STRING, 1)
            oprot.writeString(self.version.encode('utf-8') if sys.version_info[0] == 2 else self.version)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.version is None:
            raise TProtocolException(message='Required field version is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class set_cql_version_result(object):
    """
    Attributes:
     - ire
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ),  # 1
    )

    def __init__(self, ire=None,):
        self.ire = ire

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.ire = InvalidRequestException()
                    self.ire.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('set_cql_version_result')
        if self.ire is not None:
            oprot.writeFieldBegin('ire', TType.STRUCT, 1)
            self.ire.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
