Skip to content

Bindings

Xinxin (Cissie) Mei edited this page Sep 6, 2024 · 9 revisions

Python Bindings

The Python bindings for E2SAR are implemented with pybind11. You can find the source code in the 'src/pybind' directory.

Usage

The pybind11 module, named e2sar_py, is built alongside the C++ library and is named e2sar_py.cpython-<platform>.so based on the platform. To use the module, add its path to the Python environment:

# Add the path of the pybind module
import sys
sys.path.append('/path/to/e2sar_py.cpython-<platform>.so')

# Import the module
import e2sar_py
# Your Python code here

Examples

We provide Jupyter notebooks in the 'scripts/notebooks/pybind11_examples' directory to demonstrate Python usage.

  • example_DataPlane.ipynb: Shows how to use the Python Segmenter and Reassembler classes to send and receive messages without a real FPGA control plane.
  • example_EjfatURI.ipynb: Demonstrates how to create Python EjfatURI classes and handle cases where C++ functions return result<T> types.

Binding overview

We provide Python bindings for the following C++ classes. To ensure better organization, the compiled Python module e2sar_py includes two submodules: ControlPlane and DataPlane.

C++ class Python class
boost::asio::ip::address e2sar_py.IPAddress
e2sar::E2SARErrorc e2sar_py.E2SARErrorc
e2sar::E2SARErrorInfo e2sar_py.E2SARErrorInfo
e2sar::REHdr e2sar_py.REHdr
e2sar::LBHdr e2sar_py.LBHdr
e2sar::SyncHdr e2sar_py.SyncHdr
e2sar::EjfatURI e2sar_py.EjfatURI
e2sar::LBManager e2sar_py.ControlPlane.LBManager
e2sar::Segmenter e2sar_py.DataPlane.Segmenter
e2sar::Reassembler e2sar_py.DataPlane.Reassembler

Binding details

We list the C++ e2sar classes that are bound to Python and explain how their input, output, and return types are mapped to Python equivalents. Their usage is further demonstrated in the Jupyter notebook examples.

Bindings for the C++ e2sar::EjfatURI class

The C++ e2sar::EjfatURI class is mapped to the Python class e2sar_py.EjfatURI, with its public methods detailed in the table below.

Click to expand
Members C++ `e2sar::EjfatURI` class Python `e2sar_py.EjfatURI` class Notes
Enum class EjfatURI::TokenType::admin;
EjfatURI::TokenType::instance;
EjfatURI::TokenType::session;
EjfatURI.TokenType.admin
EjfatURI.TokenType.instance
EjfatURI.TokenType.session
Constructor EjfatURI(const std::string &, TokenType, bool); EjfatURI(uri: str, tt: e2sar_py.EjfatURI.TokenType, preferV6: bool) C++ and Python functions use the same default parameter values.
Get/Set LB name const std::string get_lbName();
void set_lbName(const std::string &);
EjfatURI.lb_name The C++ get and set methods are mapped to the `lb_name` attribute of type string in the Python `EjfatURI` class.
Get/Set LB ID const std::string get_lbId();
void set_lbId(const std::string &);
EjfatURI.lb_id Similar as above.
Get/Set session ID const std::string get_sessionId();
void set_sessionId(const std::string &);
EjfatURI.session_id Similar as above.
Void functions: set tokens void set_InstanceToken(const std::string &);
void set_SessionToken(const std::string &);
EjfatURI.set_instance_token(token: str) -> None
EjfatURI.set_session_token(token: str) -> None
Void functions: set IP v4/v6 addresses void set_syncAddr(const std::pair<ip::address, u_int16_t> &);
void set_dataAddr(const std::pair<ip::address, u_int16_t> &);
EjfatURI.set_sync_addr(ip_tuple: Tuple[e2sar_py.IPAddress, int]) -> None
EjfatURI.set_data_addr(ip_tuple: Tuple[e2sar_py.IPAddress, int]) -> None
The C++ `std::pair` is mapped to a Python tuple, and the C++ `ip::address` class is mapped to the Python helper class `e2sar_py.IPAddress`. You can create `e2sar_py.IPAddress` Python objects using the method `e2sar_py.IPAddress.from_string(ip_str: str)`.
Functions return a bool value bool get_useTls();
bool has_dataAddrv4();
bool has_dataAddrv6();
bool has_dataAddr();
bool has_syncAddr();
EjfatURI.get_useTls() -> bool
EjfatURI.has_data_addr_v4() -> bool
EjfatURI.has_data_addr_v6() -> bool
EjfatURI.has_data_addr() -> bool
EjfatURI.has_sync_addr() -> bool
Functions return a `result<std::string>` data type: get tokens result<std::string> get_InstanceToken();
result<std::string> get_SessionToken();
result<std::string> get_AdminToken();
EjfatURI.get_instance_token() -> e2sar_py.E2SARResultString
EjfatURI.get_session_token() -> e2sar_py.E2SARResultString
EjfatURI.get_admin_token() -> e2sar_py.E2SARResultString
The Python functions return an `e2sar_py.E2SARResultString` object `rt_obj`. The actual values can be accessed using `rt_obj.value()`. The error information can be accessed using `rt_obj.error()`.
Functions return a `result<<std::pair<ip::address, u_int16_t>>` data type: get IP addresses result<<std::pair<ip::address, u_int16_t>> get_cpAddr();
result<<std::pair<ip::address, u_int16_t>> get_dataAddrv4();
result<<std::pair<ip::address, u_int16_t>> get_dataAddrv6();
result<<std::pair<ip::address, u_int16_t>> get_syncAddr();
EjfatURI.get_cp_addr() -> e2sar_py.E2SARResultPairIP
EjfatURI.get_data_addr_v4() -> e2sar_py.E2SARResultPairIP
EjfatURI.get_data_addr_v6() -> e2sar_py.E2SARResultPairIP
EjfatURI.get_sync_addr() -> e2sar_py.E2SARResultPairIP
The Python functions return an object `rt_obj`. `rt_obj.value()` is a Python tuple, with the first element being an `e2sar_py.IPAddress` instance.
Get control plane hostname and port result<<std::string, u_int16_t>> get_cpHost(); EjfatURI.get_cp_host() -> e2sar_py.E2SARResultPairString The Python functions return an object `rt_obj`. `rt_obj.value()` is a Python tuple, with the first element being a Python string.
Cast the `EjfatURI` object to a string std::string to_string(TokenType); EjfatURI.to_string() -> str
Initialize the `EjfatURI` object from an environment variable. Returns a `result<EjfatURI>` data type. result<EjfatURI> getFromEnv(const std::string &, TokenType, bool); EjfatURI.get_from_env(env_var: str, tt: e2sar_py.EjfatURI.TokenType, preferV6: bool) -> e2sar_py.E2SARResultEjfatURI The Python function returns an `E2SARResultEjfatURI` object, where `rt_obj.value()` is an `EjfatURI` instance. C++ and Python functions use the same default parameter values.

Bindings for the C++ e2sar::LBManager class

The C++ e2sar::LBManager class is mapped to the Python LBManager class in the e2sar_py.ControlPlane submodule. The details are to be verified and finalized.

Bindings for the C++ e2sar::Segmenter class

The C++ e2sar::Segmenter class is mapped to the Python Segmenter class in the e2sar_py.DataPlane submodule, with its public methods detailed in the table below.

Click to expand
Members C++ `e2sar::Segmenter` class Python `e2sar_py.DataPlane.Segmenter` class Notes
Struct Segmenter::SegmenterFlags DataPlane.SegmenterFlags All members of the C++ struct are bound to Python.The default values are the same.
Constructor Segmenter(const EjfatURI &, u_int16_t, u_int32_t, const SegmenterFlags &); Segmenter(uri: e2sar_py.EjfatURI, data_id: int, sflags: e2sar_py.DataPlane.SegmenterFlags) C++ and Python functions use the same default parameter values.
Void function: stop threads void stopThreads(); Segmenter.stopThreads() -> None
Functions return an integer const u_int16_t getMTU();
const size_t getMaxPldLen();
Segmenter.getMTU() -> int
Segmenter.getMaxPldLen() -> int
Functions return a `boost<tuple>` data type const boost::tuple<u_int64_t, u_int64_t, int> getSendStats();
const boost::tuple<u_int64_t, u_int64_t, int> getSyncStats();
Segmenter.getSendStats() -> Tuple[int, int, int]
Segmenter.getSyncStats() -> Tuple[int, int, int]
The C++ `boost::tuple` is mapped to a Python tuple, where the first element is the sent message/frame counter, the second element is the error counter, and the last element contains the most recent error information.
Functions return a `result<int>` data type result<int> openAndStart();
result<int> sendEvent(u_int8_t *, size_t, EventNum_t, u_int16_t, u_int16_t);
result<int> addToSendQueue(u_int8_t *, size_t, EventNum_t, u_int16_t, u_int16_t, …);

Segmenter.OpenAndStart() -> e2sar_py.E2SARResultInt
Segmenter.sendEvent(send_buf: bytes, buf_len: int, _eventNum: int, _dataId: int, entropy: int) -> e2sar_py.E2SARResultInt
Segmenter.addToSendQueue(send_buf: bytes, buf_len: int, _eventNum: int, _dataId: int, entropy: int) -> e2sar_py.E2SARResultInt
`rt_obj.value()` is an integer, with 0 indicating success. The Python `send_buf` must be of type `bytes`. If sending a string `str_obj`, convert it to bytes using `str_obj.encode('utf-8')`.

Bindings for the C++ e2sar::Reassembler class

The C++ e2sar::Reassembler class is mapped to the Python Reassembler class in the e2sar_py.DataPlane submodule, with its public methods detailed in the table below.

Click to expand
Members C++ `e2sar::Reassembler` class Python `e2sar_py.DataPlane.Reassembler` class Notes
Struct Reassembler::ReassemblerFlags DataPlane.ReassemblerFlags All members of the C++ struct are bound to Python. The default values are the same.
Constructor: Initialize with the number of receiving threads. Reassembler(const EjfatURI &, size_t, const ReassemblerFlags &); Reassembler(uri: e2sar_py.EjfatURI, num_recv_threads: int, rflags: e2sar_py.DataPlane.ReassemblerFlags) C++ and Python functions use the same default parameter values.
Void function: stop threads void stopThreads(); Reassembler.stopThreads() -> None
Get the port range: (start_port, end_port) const std::pair<int, int>get_recvPorts(); Reassembler.get_recvPorts() -> Tuple[int, int]
Functions return an integer const int get_portRange();
const size_t get_numRecvThreads();
Reassembler.get_portRange() -> int
Reassembler.get_numRecvThreads() -> int
Function return a `boost<tuple>` data type const boost::tuple<EventNum_t, EventNum_t, int lastErrno, int grpcErrCnt, int dataErrCnt, E2SARErrorc> getStats(); Reassembler.getStats() -> Tuple[int, int, int, int, int, e2sar_py.E2SARErrorc] The C++ `boost::tuple` is mapped to a Python tuple. The C++ `e2sar::E2SARErrorc` class is mapped to the Python `e2sar_py.E2SARErrorc` class.
Functions to receive events result<int> getEvent(uint8_t **, size_t *, EventNum_t*, uint16_t *);
result<int> recvEvent(uint8_t **, size_t *, EventNum_t*, uint16_t *);

Reassembler.getEvent(recv_buf: List) -> Tuple[int, int, int, int]
Reassembler.recvEvent(recv_buf: List) -> Tuple[int, int, int, int]
The Python `recv_buf` is a mutable object, initialized with `recv_buf=[None]`. The returned Python tuple is structured as(fail_flag, buf_len, _eventNum, _dataId to align with the `e2sar::segmenter` parameters. When the function executes successfully, `fail_flag` will be 0, and `recv_buf` will be populated with the received events.
Functions return a `result<int>` data type result<int> openAndStart();
result<int> registerWorker(const std::string &, float, float, float);
result<int> deregisterWorker();

Reassembler.OpenAndStart() -> e2sar_py.E2SARResultInt
Reassembler.registerWorker(node_name: str, float weight, float min_factor, float max_factor) -> e2sar_py.E2SARResultInt
Reassembler.deregisterWorker() -> e2sar_py.E2SARResultInt
`rt_obj.value()` is an integer, with 0 indicating success.