# cassandra.protocol

Protocol Features

<a id="module-cassandra.protocol"></a>

<a id="custom-payload"></a>

## Custom Payloads

Native protocol version 4+ allows for a custom payload to be sent between clients
and custom query handlers. The payload is specified as a string:binary_type dict
holding custom key/value pairs.

By default these are ignored by the server. They can be useful for servers implementing
a custom QueryHandler.

See [`Session.execute()`](https://python-driver.docs.scylladb.com/stable/api/cassandra/cluster.md#cassandra.cluster.Session.execute), [`Session.execute_async()`](https://python-driver.docs.scylladb.com/stable/api/cassandra/cluster.md#cassandra.cluster.Session.execute_async), [`ResponseFuture.custom_payload`](https://python-driver.docs.scylladb.com/stable/api/cassandra/cluster.md#cassandra.cluster.ResponseFuture.custom_payload).

### *class* cassandra.protocol.\_ProtocolHandler

\_ProtocolHander handles encoding and decoding messages.

This class can be specialized to compose Handlers which implement alternative
result decoding or type deserialization. Class definitions are passed to [`cassandra.cluster.Cluster`](https://python-driver.docs.scylladb.com/stable/api/cassandra/cluster.md#cassandra.cluster.Cluster)
on initialization.

Contracted class methods are [`_ProtocolHandler.encode_message()`](#cassandra.protocol._ProtocolHandler.encode_message) and [`_ProtocolHandler.decode_message()`](#cassandra.protocol._ProtocolHandler.decode_message).

#### message_types_by_opcode *= {default mapping}*

Default mapping of opcode to Message implementation. The default `decode_message` implementation uses
this to instantiate a message and populate using `recv_body`. This mapping can be updated to inject specialized
result decoding implementations.

#### *classmethod* encode_message(msg, stream_id, protocol_version, compressor, allow_beta_protocol_version)

Encodes a message using the specified frame parameters, and compressor

* **Parameters:**
  * **msg** – the message, typically of cassandra.protocol._MessageType, generated by the driver
  * **stream_id** – protocol stream id for the frame header
  * **protocol_version** – version for the frame header, and used encoding contents
  * **compressor** – optional compression function to be used on the body

#### *classmethod* decode_message(protocol_version, protocol_features, user_type_map, stream_id, flags, opcode, body, decompressor, result_metadata)

Decodes a native protocol message body

* **Parameters:**
  * **protocol_version** – version to use decoding contents
  * **user_type_map** – map[keyspace name] = map[type name] = custom type to instantiate when deserializing this type
  * **stream_id** – native protocol stream id from the frame header
  * **flags** – native protocol flags bitmap from the header
  * **opcode** – native protocol opcode from the header
  * **body** – frame body
  * **decompressor** – optional decompression function to inflate the body
* **Returns:**
  a message decoded from the body and frame attributes

<a id="faster-deser"></a>

## Faster Deserialization

When python-driver is compiled with Cython, it uses a Cython-based deserialization path
to deserialize messages. By default, the driver will use a Cython-based parser that returns
lists of rows similar to the pure-Python version. In addition, there are two additional
ProtocolHandler classes that can be used to deserialize response messages: `LazyProtocolHandler`
and `NumpyProtocolHandler`. They can be used as follows:

```python
from cassandra.protocol import NumpyProtocolHandler, LazyProtocolHandler
from cassandra.query import tuple_factory
s.client_protocol_handler = LazyProtocolHandler   # for a result iterator
s.row_factory = tuple_factory  #required for Numpy results
s.client_protocol_handler = NumpyProtocolHandler  # for a dict of NumPy arrays as result
```

These protocol handlers comprise different parsers, and return results as described below:

- ProtocolHandler: this default implementation is a drop-in replacement for the pure-Python version.
  The rows are all parsed upfront, before results are returned.
- LazyProtocolHandler: near drop-in replacement for the above, except that it returns an iterator over rows,
  lazily decoded into the default row format (this is more efficient since all decoded results are not materialized at once)
- NumpyProtocolHandler: deserializes results directly into NumPy arrays. This facilitates efficient integration with
  analysis toolkits such as Pandas.
