-
Notifications
You must be signed in to change notification settings - Fork 0
Bindings
The Python bindings for E2SAR are implemented with pybind11. You can find the source code in the 'src/pybind' directory.
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
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
andReassembler
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 returnresult<T>
types.
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 |
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.
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.value()`. |
Functions return a `result<<std::pai<ip::address, u_int16_t>>` data type: get IP addresses | result<<std::pai<ip::address, u_int16_t>> get_cpAddr();
result<<std::pai<ip::address, u_int16_t>> get_dataAddrv4(); result<<std::pai<ip::address, u_int16_t>> get_dataAddrv6(); result<<std::pai<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 whose `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 whose `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 tt, 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 the `value` attribute is an `EjfatURI` instance. C++ and Python functions use the same default parameter values. |
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.
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 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 _eventNum, u_int16_t, u_int16_t entropy); result<int> addToSendQueue(u_int8_t *, size_t, EventNum_t _eventNum, u_int16_t, u_int16_t entropy, ...); |
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 |
The `value()` of the returned Python object 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')`. |
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 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 |
The `value()` of the returned Python object is an integer, with 0 indicating success. |