<!--

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->
# Python Native API

IoTDB provides a Python native client driver and a session pool management mechanism. These tools allow developers to interact with IoTDB in a programmatic and efficient manner. Using the Python API, developers can encapsulate time-series data into objects (e.g., `Tablet`, `NumpyTablet`) and insert them into the database directly, without the need to manually construct SQL statements. For multi-threaded operations, the `TableSessionPool` is recommended to optimize resource utilization and enhance performance.

## 1. Prerequisites

To use the IoTDB Python API, install the required package using pip:

```shell
pip3 install apache-iotdb>=2.0
```
Note: Do not use a newer client to connect to an older server, as this may cause connection failures or unexpected errors.

## 2. Read and Write Operations

### 2.1 TableSession

`TableSession` is a core class in IoTDB, enabling users to interact with the IoTDB database. It provides methods to execute SQL statements, insert data, and manage database sessions.

#### Method Overview

| **Method Name**             | **Descripton**                                        | **Parameter Type**                   | **Return Type**  |
| --------------------------- | ----------------------------------------------------- | ------------------------------------ | ---------------- |
| insert                      | Inserts data into the database.                       | tablet: `Union[Tablet, NumpyTablet]` | None             |
| execute_non_query_statement | Executes non-query SQL statements like DDL/DML.       | sql: `str`                           | None             |
| execute_query_statement     | Executes a query SQL statement and retrieves results. | sql: `str`                           | `SessionDataSet` |
| close                       | Closes the session and releases resources.            | None                                 | None             |

**Since V2.0.8.2**, `SessionDataSet` provides methods for batch DataFrame retrieval to efficiently handle large-volume queries:

```python
# Batch DataFrame retrieval
has_next = result.has_next_df()
if has_next:
    df = result.next_df()
    # Process DataFrame
```

**Method Details:**
- `has_next_df()`: Returns `True`/`False` indicating whether more data exists
- `next_df()`: Returns a `DataFrame` or `None`. Each call returns `fetchSize` rows (default: 5000 rows, controlled by Session's `fetch_size` parameter):
    - If remaining data ≥ `fetchSize`: returns `fetchSize` rows
    - If remaining data < `fetchSize`: returns all remaining rows
    - If traversal completes: returns `None`
- Session validates `fetchSize` at initialization: if ≤0, resets to 5000 and logs warning: `fetch_size xxx is illegal, use default fetch_size 5000`

**Note:** Avoid mixing different traversal methods (e.g., combining `todf()` with `next_df()`), which may cause unexpected errors.

**Since V2.0.8.3**, the Python client has supported `TSDataType.OBJECT` for Tablet batch write and Session value serialization. Query results are read via the `Field` object. The related interfaces are defined as follows:

| Function Name | Description | Parameters | Return Value |
|---------------|-------------|------------|--------------|
| `encode_object_cell` | Encodes a single OBJECT cell into wire-format bytes | `is_eof: bool`,<br>`offset: int`,<br>`content: bytes` | `bytes`: `\|[eof 1B]\|[offset 8B BE]\|[payload]\|` |
| `decode_object_cell` | Parses a wire-format cell back into `eof`, `offset`, and `payload` | `cell: bytes` (length ≥ 9) | `Tuple[bool, int, bytes]`: `(is_eof, offset, payload)` |
| `Tablet.add_value_object` | Writes an OBJECT cell at the specified row and column (internally calls `encode_object_cell`) | `row_index: int`,<br>`column_index: int`,<br>`is_eof: bool`,<br>`offset: int`,<br>`content: bytes` | `None` |
| `Tablet.add_value_object_by_name` | Same as above, locates column by name | `column_name: str`,<br>`row_index: int`,<br>`is_eof: bool`,<br>`offset: int`,<br>`content: bytes` | `None` |
| `NumpyTablet.add_value_object` | Same semantics as `Tablet.add_value_object`, column data is stored as `ndarray` | Same as above (`row_index`, `column_index`, ...) | `None` |
| `Field.get_object_value` | Converts the value to a Python value based on the **target type** | `data_type: TSDataType` | Depends on type:<br>For OBJECT: `str` decoded from the entire `self.value` in UTF-8 (see Field.py) |
| `Field.get_string_value` | Returns a string representation | None | `str`;<br>For OBJECT: `self.value.decode("utf-8")` |
| `Field.get_binary_value` | Gets the binary data of TEXT/STRING/BLOB | None | `bytes` or `None`;<br>**Throws an error for OBJECT columns and should not be called** |


#### Sample Code

```Python
class TableSession(object):
def insert(self, tablet: Union[Tablet, NumpyTablet]):
    """
    Insert data into the database.

    Parameters:
        tablet (Tablet | NumpyTablet): The tablet containing the data to be inserted.
                                       Accepts either a `Tablet` or `NumpyTablet`.

    Raises:
        IoTDBConnectionException: If there is an issue with the database connection.
    """
    pass

def execute_non_query_statement(self, sql: str):
    """
    Execute a non-query SQL statement.

    Parameters:
        sql (str): The SQL statement to execute. Typically used for commands
                   such as INSERT, DELETE, or UPDATE.

    Raises:
        IoTDBConnectionException: If there is an issue with the database connection.
    """
    pass

def execute_query_statement(self, sql: str, timeout_in_ms: int = 0) -> "SessionDataSet":
    """
    Execute a query SQL statement and return the result set.

    Parameters:
        sql (str): The SQL query to execute.
        timeout_in_ms (int, optional): Timeout for the query in milliseconds. Defaults to 0,
                                       which means no timeout.

    Returns:
        SessionDataSet: The result set of the query.

    Raises:
        IoTDBConnectionException: If there is an issue with the database connection.
    """
    pass

def close(self):
    """
    Close the session and release resources.

    Raises:
        IoTDBConnectionException: If there is an issue closing the connection.
    """
    pass
```

### 2.2 TableSessionConfig

`TableSessionConfig` is a configuration class that sets parameters for creating a `TableSession` instance, defining essential settings for connecting to the IoTDB database.

#### Parameter Configuration

| **Parameter**      | **Description**                       | **Type** | **Default Value**                             |
| ------------------ | ------------------------------------- | -------- |-----------------------------------------------|
| node_urls          | List of database node URLs.           | `list`   | `["localhost:6667"]`                          |
| username           | Username for the database connection. | `str`    | `"root"`                                      |
| password           | Password for the database connection. | `str`    | `"TimechoDB@2021"`，before V2.0.6 it is root   |
| database           | Target database to connect to.        | `str`    | `None`                                        |
| fetch_size         | Number of rows to fetch per query.    | `int`    | `5000`                                        |
| time_zone          | Default session time zone.            | `str`    | `Session.DEFAULT_ZONE_ID`                     |
| enable_compression | Enable data compression.              | `bool`   | `False`                                       |

#### Sample Code

```Python
class TableSessionConfig(object):
    """
    Configuration class for a TableSession. 

    This class defines various parameters for connecting to and interacting 
    with the IoTDB tables.
    """

    def __init__(
        self,
        node_urls: list = None,
        username: str = Session.DEFAULT_USER,
        password: str = Session.DEFAULT_PASSWORD,
        database: str = None,
        fetch_size: int = 5000,
        time_zone: str = Session.DEFAULT_ZONE_ID,
        enable_compression: bool = False,
    ):
        """
        Initialize a TableSessionConfig object with the provided parameters.

        Parameters:
            node_urls (list, optional): A list of node URLs for the database connection.
                                        Defaults to ["localhost:6667"].
            username (str, optional): The username for the database connection. 
                                      Defaults to "root".
            password (str, optional): The password for the database connection. 
                                      Defaults to "TimechoDB@2021"，before V2.0.6 it is root
            database (str, optional): The target database to connect to. Defaults to None.
            fetch_size (int, optional): The number of rows to fetch per query. Defaults to 5000.
            time_zone (str, optional): The default time zone for the session. 
                                       Defaults to Session.DEFAULT_ZONE_ID.
            enable_compression (bool, optional): Whether to enable data compression. 
                                                 Defaults to False.
        """
```

**Note:** After using a `TableSession`, make sure to call the `close` method to release resources.

## 3. Session Pool

### 3.1 TableSessionPool

`TableSessionPool` is a session pool management class designed for creating and managing `TableSession` instances. It provides functionality to retrieve sessions from the pool and close the pool when it is no longer needed.

#### Method Overview

| **Method Name** | **Description**                                        | **Return Type** | **Exceptions** |
| --------------- | ------------------------------------------------------ | --------------- | -------------- |
| get_session     | Retrieves a new `TableSession` instance from the pool. | `TableSession`  | None           |
| close           | Closes the session pool and releases all resources.    | None            | None           |

#### Sample Code

```Python
def get_session(self) -> TableSession:
    """
    Retrieve a new TableSession instance.

    Returns:
        TableSession: A new session object configured with the session pool.

    Notes:
        The session is initialized with the underlying session pool for managing
        connections. Ensure proper usage of the session's lifecycle.
    """

def close(self):
    """
    Close the session pool and release all resources.

    This method closes the underlying session pool, ensuring that all
    resources associated with it are properly released.

    Notes:
        After calling this method, the session pool cannot be used to retrieve
        new sessions, and any attempt to do so may raise an exception.
    """
```

### 3.2 TableSessionPoolConfig

`TableSessionPoolConfig` is a configuration class used to define parameters for initializing and managing a `TableSessionPool` instance. It specifies the settings needed for efficient session pool management in IoTDB.

#### Parameter Configuration

| **Paramater**      | **Description**                                              | **Type** | **Default Value**          |
| ------------------ | ------------------------------------------------------------ | -------- | -------------------------- |
| node_urls          | List of IoTDB cluster node URLs.                             | `list`   | None                       |
| max_pool_size      | Maximum size of the session pool, i.e., the maximum number of sessions allowed in the pool. | `int`    | `5`                        |
| username           | Username for the connection.                                 | `str`    | `Session.DEFAULT_USER`     |
| password           | Password for the connection.                                 | `str`    | `Session.DEFAULT_PASSWORD` |
| database           | Target database to connect to.                               | `str`    | None                       |
| fetch_size         | Fetch size for query results                                 | `int`    | `5000`                     |
| time_zone          | Timezone-related `ZoneId`                                    | `str`    | `Session.DEFAULT_ZONE_ID`  |
| enable_redirection | Whether to enable redirection.                               | `bool`   | `False`                    |
| enable_compression | Whether to enable data compression.                          | `bool`   | `False`                    |
| wait_timeout_in_ms | Sets the connection timeout in milliseconds.                 | `int`    | `10000`                    |
| max_retry          | Maximum number of connection retry attempts.                 | `int`    | `3`                        |

#### Sample Code

```Python
class TableSessionPoolConfig(object):
    """
    Configuration class for a TableSessionPool.

    This class defines the parameters required to initialize and manage
    a session pool for interacting with the IoTDB database.
    """
    def __init__(
        self,
        node_urls: list = None,
        max_pool_size: int = 5,
        username: str = Session.DEFAULT_USER,
        password: str = Session.DEFAULT_PASSWORD,
        database: str = None,
        fetch_size: int = 5000,
        time_zone: str = Session.DEFAULT_ZONE_ID,
        enable_redirection: bool = False,
        enable_compression: bool = False,
        wait_timeout_in_ms: int = 10000,
        max_retry: int = 3,
    ):
    """
    Initialize a TableSessionPoolConfig object with the provided parameters.
    
    Parameters:
        node_urls (list, optional): A list of node URLs for the database connection.
                                    Defaults to None.
        max_pool_size (int, optional): The maximum number of sessions in the pool.
                                       Defaults to 5.
        username (str, optional): The username for the database connection.
                                  Defaults to Session.DEFAULT_USER.
        password (str, optional): The password for the database connection.
                                  Defaults to Session.DEFAULT_PASSWORD.
        database (str, optional): The target database to connect to. Defaults to None.
        fetch_size (int, optional): The number of rows to fetch per query. Defaults to 5000.
        time_zone (str, optional): The default time zone for the session pool.
                                   Defaults to Session.DEFAULT_ZONE_ID.
        enable_redirection (bool, optional): Whether to enable redirection.
                                             Defaults to False.
        enable_compression (bool, optional): Whether to enable data compression.
                                             Defaults to False.
        wait_timeout_in_ms (int, optional): The maximum time (in milliseconds) to wait for a session
                                            to become available. Defaults to 10000.
        max_retry (int, optional): The maximum number of retry attempts for operations. Defaults to 3.
    
    """
```

**Notes:**

- Ensure that `TableSession` instances retrieved from the `TableSessionPool` are properly closed after use.
- After closing the `TableSessionPool`, it will no longer be possible to retrieve new sessions.

### 3.3 SSL Connection

#### 3.3.1 Server Certificate Configuration

In the `conf/iotdb-system.properties` configuration file, locate or add the following configuration items:

```
enable_thrift_ssl=true
key_store_path=/path/to/your/server_keystore.jks
key_store_pwd=your_keystore_password
```

#### 3.3.2 Configure Python Client Certificate

- Set `use_ssl` to True to enable SSL.
- Specify the client certificate path using the `ca_certs` parameter.

```
use_ssl = True
ca_certs = "/path/to/your/server.crt"  # 或 ca_certs = "/path/to/your//ca_cert.pem"
```
**Example Code: Using SSL to Connect to IoTDB**

```Python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from iotdb.SessionPool import PoolConfig, SessionPool
from iotdb.Session import Session

ip = "127.0.0.1"
port_ = "6667"
username_ = "root"
password_ = "TimechoDB@2021"，before V2.0.6 it is root
# Configure SSL enabled
use_ssl = True
# Configure certificate path
ca_certs = "/path/server.crt"


def get_data():
    session = Session(
        ip, port_, username_, password_, use_ssl=use_ssl, ca_certs=ca_certs
    )
    session.open(False)
    with session.execute_query_statement("SHOW DATABASES") as session_data_set:
        print(session_data_set.get_column_names())
        while session_data_set.has_next():
            print(session_data_set.next())

    session.close()


def get_data2():
    pool_config = PoolConfig(
        host=ip,
        port=port_,
        user_name=username_,
        password=password_,
        fetch_size=1024,
        time_zone="UTC+8",
        max_retry=3,
        use_ssl=use_ssl,
        ca_certs=ca_certs,
    )
    max_pool_size = 5
    wait_timeout_in_ms = 3000
    session_pool = SessionPool(pool_config, max_pool_size, wait_timeout_in_ms)
    session = session_pool.get_session()
    with session.execute_query_statement("SHOW DATABASES") as session_data_set:
        print(session_data_set.get_column_names())
        while session_data_set.has_next():
            print(session_data_set.next())
    session_pool.put_back(session)
    session_pool.close()


if __name__ == "__main__":
    df = get_data()
```

## 4. Sample Code

**Session** Example: You can find the full example code at [Session Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/table_model_session_example.py).

**Session Pool** Example: You can find the full example code at [SessionPool Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/table_model_session_pool_example.py).

Here is an excerpt of the sample code:

```Python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
import threading

import numpy as np

from iotdb.table_session_pool import TableSessionPool, TableSessionPoolConfig
from iotdb.utils.IoTDBConstants import TSDataType
from iotdb.utils.NumpyTablet import NumpyTablet
from iotdb.utils.Tablet import ColumnType, Tablet


def prepare_data():
    print("create database")
    # Get a session from the pool
    session = session_pool.get_session()
    session.execute_non_query_statement("CREATE DATABASE IF NOT EXISTS db1")
    session.execute_non_query_statement('USE "db1"')
    session.execute_non_query_statement(
        "CREATE TABLE table0 (id1 string id, attr1 string attribute, "
        + "m1 double "
        + "field)"
    )
    session.execute_non_query_statement(
        "CREATE TABLE table1 (id1 string tag, attr1 string attribute, "
        + "m1 double "
        + "field)"
    )

    print("now the tables are:")
    # show result
    with session.execute_query_statement("SHOW TABLES") as res:
        while res.has_next():
            print(res.next())

    session.close()


def insert_data(num: int):
    print("insert data for table" + str(num))
    # Get a session from the pool
    session = session_pool.get_session()
    column_names = [
        "id1",
        "attr1",
        "m1",
    ]
    data_types = [
        TSDataType.STRING,
        TSDataType.STRING,
        TSDataType.DOUBLE,
    ]
    column_types = [ColumnType.TAG, ColumnType.ATTRIBUTE, ColumnType.FIELD]
    timestamps = []
    values = []
    for row in range(15):
        timestamps.append(row)
        values.append(["id:" + str(row), "attr:" + str(row), row * 1.0])
    tablet = Tablet(
        "table" + str(num), column_names, data_types, values, timestamps, column_types
    )
    session.insert(tablet)
    session.execute_non_query_statement("FLush")

    np_timestamps = np.arange(15, 30, dtype=np.dtype(">i8"))
    np_values = [
        np.array(["id:{}".format(i) for i in range(15, 30)]),
        np.array(["attr:{}".format(i) for i in range(15, 30)]),
        np.linspace(15.0, 29.0, num=15, dtype=TSDataType.DOUBLE.np_dtype()),
    ]

    np_tablet = NumpyTablet(
        "table" + str(num),
        column_names,
        data_types,
        np_values,
        np_timestamps,
        column_types=column_types,
    )
    session.insert(np_tablet)
    session.close()


def query_data():
    # Get a session from the pool
    session = session_pool.get_session()

    print("get data from table0")
    with session.execute_query_statement("select * from table0") as res:
        while res.has_next():
            print(res.next())

    print("get data from table1") 
    with session.execute_query_statement("select * from table1") as res:
      while res.has_next():
          print(res.next())
        
    # Querying Table Data Using Batch DataFrame (Recommended for Large Datasets)
    print("get data from table0 using batch DataFrame")
    with session.execute_query_statement("select * from table0") as res: 
      while res.has_next_df(): 
          print(res.next_df()) 
         
    session.close()


def delete_data():
    session = session_pool.get_session()
    session.execute_non_query_statement("drop database db1")
    print("data has been deleted. now the databases are:")
    with session.execute_query_statement("show databases") as res:
        while res.has_next():
            print(res.next())
    session.close()


# Create a session pool
username = "root"
password = "TimechoDB@2021"，before V2.0.6 it is root
node_urls = ["127.0.0.1:6667", "127.0.0.1:6668", "127.0.0.1:6669"]
fetch_size = 1024
database = "db1"
max_pool_size = 5
wait_timeout_in_ms = 3000
config = TableSessionPoolConfig(
    node_urls=node_urls,
    username=username,
    password=password,
    database=database,
    max_pool_size=max_pool_size,
    fetch_size=fetch_size,
    wait_timeout_in_ms=wait_timeout_in_ms,
)
session_pool = TableSessionPool(config)

prepare_data()

insert_thread1 = threading.Thread(target=insert_data, args=(0,))
insert_thread2 = threading.Thread(target=insert_data, args=(1,))

insert_thread1.start()
insert_thread2.start()

insert_thread1.join()
insert_thread2.join()

query_data()
delete_data()
session_pool.close()
print("example is finished!")
```

**Object Type Usage Example**

```python
import os

import numpy as np
import pytest

from iotdb.utils.IoTDBConstants import TSDataType
from iotdb.utils.NumpyTablet import NumpyTablet
from iotdb.utils.Tablet import Tablet, ColumnType
from iotdb.utils.object_column import decode_object_cell


def _require_thrift():
    pytest.importorskip("iotdb.thrift.common.ttypes")


def _session_endpoint():
    host = os.environ.get("IOTDB_HOST", "127.0.0.1")
    port = int(os.environ.get("IOTDB_PORT", "6667"))
    return host, port


@pytest.fixture(scope="module")
def table_session():
    _require_thrift()
    from iotdb.Session import Session
    from iotdb.table_session import TableSession, TableSessionConfig

    host, port = _session_endpoint()
    cfg = TableSessionConfig(
        node_urls=[f"{host}:{port}"],
        username=os.environ.get("IOTDB_USER", Session.DEFAULT_USER),
        password=os.environ.get("IOTDB_PASSWORD", Session.DEFAULT_PASSWORD),
    )
    ts = TableSession(cfg)
    yield ts
    ts.close()


def test_table_numpy_tablet_object_columns(table_session):
    """
    Table model: Tablet.add_value_object / add_value_object_by_name,
    NumpyTablet.add_value_object, insert + query Field + decode_object_cell;
    Also includes writing OBJECT in two segments at the same timestamp
    (first with is_eof=False/offset=0, then with is_eof=True/offset=length of the first segment),
    and verifies the complete concatenated bytes using read_object(f1).
    """
    db = "test_py_object_e2e"
    table = "obj_tbl"
    table_session.execute_non_query_statement(f"CREATE DATABASE IF NOT EXISTS {db}")
    table_session.execute_non_query_statement(f"USE {db}")
    table_session.execute_non_query_statement(f"DROP TABLE IF EXISTS {table}")
    table_session.execute_non_query_statement(
        f"CREATE TABLE {table}("
        "device STRING TAG, temp FLOAT FIELD, f1 OBJECT FIELD, f2 OBJECT FIELD)"
    )

    column_names = ["device", "temp", "f1", "f2"]
    data_types = [
        TSDataType.STRING,
        TSDataType.FLOAT,
        TSDataType.OBJECT,
        TSDataType.OBJECT,
    ]
    column_types = [
        ColumnType.TAG,
        ColumnType.FIELD,
        ColumnType.FIELD,
        ColumnType.FIELD,
    ]
    timestamps = [100, 200]
    values = [
        ["d1", 1.5, None, None],
        ["d1", 2.5, None, None],
    ]

    tablet = Tablet(
        table, column_names, data_types, values, timestamps, column_types
    )
    tablet.add_value_object(0, 2, True, 0, b"first-row-obj")
    # Single-segment write for the entire object: is_eof=True and offset=0;
    # Segmented sequential writes must pass server-side offset/length validation
    tablet.add_value_object_by_name("f2", 0, True, 0, b"seg")
    tablet.add_value_object(1, 2, True, 0, b"second-f1")
    tablet.add_value_object(1, 3, True, 0, b"second-f2")
    table_session.insert(tablet)

    ts_arr = np.array([300, 400], dtype=TSDataType.INT64.np_dtype())
    np_vals = [
        np.array(["d1", "d1"]),
        np.array([1.0, 2.0], dtype=np.float32),
        np.array([None, None], dtype=object),
        np.array([None, None], dtype=object),
    ]
    np_tab = NumpyTablet(
        table, column_names, data_types, np_vals, ts_arr, column_types=column_types
    )
    np_tab.add_value_object(0, 2, True, 0, b"np-r0-f1")
    np_tab.add_value_object(0, 3, True, 0, b"np-r0-f2")
    np_tab.add_value_object(1, 2, True, 0, b"np-r1-f1")
    np_tab.add_value_object(1, 3, True, 0, b"np-r1-f2")
    table_session.insert(np_tab)

    # Segmented OBJECT: first with is_eof=False (continue transmission),
    # then with is_eof=True (last segment); offset is the length of written bytes
    chunk0 = bytes((i % 256) for i in range(512))
    chunk1 = b"\xab" * 64
    expected_segmented = chunk0 + chunk1
    seg1 = Tablet(
        table,
        column_names,
        data_types,
        [["d1", 3.0, None, None]],
        [500],
        column_types,
    )
    seg1.add_value_object(0, 2, False, 0, chunk0)
    seg1.add_value_object(0, 3, True, 0, b"f2-seg")
    table_session.insert(seg1)
    seg2 = Tablet(
        table,
        column_names,
        data_types,
        [["d1", 3.0, None, None]],
        [500],
        column_types,
    )
    seg2.add_value_object(0, 2, True, 512, chunk1)
    seg2.add_value_object(0, 3, True, 0, b"f2-seg")
    table_session.insert(seg2)

    with table_session.execute_query_statement(
        f"SELECT read_object(f1) FROM {table} WHERE time = 500"
    ) as ds:
        assert ds.has_next()
        row = ds.next()
        blob = row.get_fields()[0].get_binary_value()
        assert blob == expected_segmented
        assert not ds.has_next()

    seen = 0
    with table_session.execute_query_statement(
        f"SELECT device, temp, f1, f2 FROM {table} ORDER BY time"
    ) as ds:
        while ds.has_next():
            row = ds.next()
            fields = row.get_fields()
            assert fields[0].get_object_value(TSDataType.STRING) == "d1"
            assert fields[1].get_object_value(TSDataType.FLOAT) is not None
            for j in (2, 3):
                raw = fields[j].value
                assert isinstance(raw, (bytes, bytearray))
                eof, off, body = decode_object_cell(bytes(raw))
                assert isinstance(eof, bool) and isinstance(off, int)
                assert isinstance(body, bytes)
                fields[j].get_string_value()
                fields[j].get_object_value(TSDataType.OBJECT)
            seen += 1
    assert seen == 5


if __name__ == "__main__":
    pytest.main([__file__, "-v", "-rs"])
```
