diff mbox series

[ovs-dev,v1,06/18] python: add flow base class

Message ID 20211122112256.2011194-7-amorenoz@redhat.com
State Changes Requested
Headers show
Series python: add flow parsing library | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test fail github build: failed

Commit Message

Adrian Moreno Nov. 22, 2021, 11:22 a.m. UTC
It simplifies the implementation of different types of flows by creating
the concept of Section (e.g: match, action) and automatic accessors for
all the provided Sections

Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
---
 python/automake.mk       |  3 +-
 python/ovs/flows/flow.py | 94 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 python/ovs/flows/flow.py

Comments

Eelco Chaudron Dec. 17, 2021, 3:12 p.m. UTC | #1
Some minor comments below.

//Eelco


On 22 Nov 2021, at 12:22, Adrian Moreno wrote:

> It simplifies the implementation of different types of flows by creating
> the concept of Section (e.g: match, action) and automatic accessors for
> all the provided Sections
>
> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
> ---
>  python/automake.mk       |  3 +-
>  python/ovs/flows/flow.py | 94 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 96 insertions(+), 1 deletion(-)
>  create mode 100644 python/ovs/flows/flow.py
>
> diff --git a/python/automake.mk b/python/automake.mk
> index 9dfc62fce..136da26bd 100644
> --- a/python/automake.mk
> +++ b/python/automake.mk
> @@ -45,7 +45,8 @@ ovs_pyfiles = \
>  	python/ovs/flows/__init__.py \
>  	python/ovs/flows/decoders.py \
>  	python/ovs/flows/kv.py \
> -	python/ovs/flows/list.py
> +	python/ovs/flows/list.py \
> +	python/ovs/flows/flow.py

Keep the entries in alphabetical order.


>
>  # These python files are used at build time but not runtime,
>  # so they are not installed.
> diff --git a/python/ovs/flows/flow.py b/python/ovs/flows/flow.py
> new file mode 100644
> index 000000000..ad5846c0b
> --- /dev/null
> +++ b/python/ovs/flows/flow.py
> @@ -0,0 +1,94 @@
> +""" Defines the Flow class
> +"""
> +
> +
> +class Section(object):
> +    """A section within a Flow

Can you add some more details on what a section in a flow stands for?

> +    Attributes:
> +        name (str): name of the section
> +        pos (int): position within the overall flow string
> +        string (str): section string
> +        data (list[KeyValue]): parsed data of the section
> +        is_list (bool): whether the key-values shall be expressed as a list
> +            (e.g: it allows repeated keys)
> +    """
> +
> +    def __init__(self, name, pos, string, data, is_list=False):
> +        self.name = name
> +        self.pos = pos
> +        self.string = string
> +        self.data = data
> +        self.is_list = is_list
> +
> +    def __str__(self):
> +        return "{} (at {}): {}".format(self.name, self.pos, self.string)
> +
> +    def __repr__(self):
> +        return "%s('%s')" % (self.__class__.__name__, self)
> +
> +    def dict(self):
> +        return {self.name: self.format_data()}
> +
> +    def format_data(self):
> +        if self.is_list:
> +            return [{item.key: item.value} for item in self.data]
> +        else:
> +            return {item.key: item.value for item in self.data}
> +
> +
> +class Flow(object):
> +    """The Flow class is a base class for other types of concrete flows
> +    (such as OFproto Flows or DPIF Flows)

Add dots at the end of sentences.

> +    For each section provided, the object will have the following attributes
> +    {section} will return the sections data in a formatted way
> +    {section}_kv will return the sections data as a list of KeyValues
> +
> +    Args:
> +        sections (list[Section]): list of sections that comprise the flow

Capital L for List.

> +        orig (str): Original flow string
> +        id (Any): Identifier
> +    """
> +
> +    def __init__(self, sections, orig="", id=None):
> +        self._sections = sections
> +        self._orig = orig
> +        self._id = id
> +        for section in sections:
> +            setattr(
> +                self, section.name, self.section(section.name).format_data()
> +            )
> +            setattr(
> +                self,
> +                "{}_kv".format(section.name),
> +                self.section(section.name).data,
> +            )
> +
> +    def section(self, name):
> +        """Return the section by name"""
> +        return next(
> +            (sect for sect in self._sections if sect.name == name), None
> +        )
> +
> +    @property
> +    def id(self):
> +        """Return the Flow ID"""
> +        return self._id
> +
> +    @property
> +    def sections(self):
> +        """Return the section by name"""

Cut/pase error on doctext

> +        return self._sections
> +
> +    @property
> +    def orig(self):
> +        return self._orig
> +
> +    def dict(self):
> +        """Returns the Flow information in a dictionary"""
> +        flow_dict = {"orig": self.orig}
> +        for section in self.sections:
> +            flow_dict.update(section.dict())
> +
> +        return flow_dict
> -- 
> 2.31.1
diff mbox series

Patch

diff --git a/python/automake.mk b/python/automake.mk
index 9dfc62fce..136da26bd 100644
--- a/python/automake.mk
+++ b/python/automake.mk
@@ -45,7 +45,8 @@  ovs_pyfiles = \
 	python/ovs/flows/__init__.py \
 	python/ovs/flows/decoders.py \
 	python/ovs/flows/kv.py \
-	python/ovs/flows/list.py
+	python/ovs/flows/list.py \
+	python/ovs/flows/flow.py
 
 # These python files are used at build time but not runtime,
 # so they are not installed.
diff --git a/python/ovs/flows/flow.py b/python/ovs/flows/flow.py
new file mode 100644
index 000000000..ad5846c0b
--- /dev/null
+++ b/python/ovs/flows/flow.py
@@ -0,0 +1,94 @@ 
+""" Defines the Flow class
+"""
+
+
+class Section(object):
+    """A section within a Flow
+
+    Attributes:
+        name (str): name of the section
+        pos (int): position within the overall flow string
+        string (str): section string
+        data (list[KeyValue]): parsed data of the section
+        is_list (bool): whether the key-values shall be expressed as a list
+            (e.g: it allows repeated keys)
+    """
+
+    def __init__(self, name, pos, string, data, is_list=False):
+        self.name = name
+        self.pos = pos
+        self.string = string
+        self.data = data
+        self.is_list = is_list
+
+    def __str__(self):
+        return "{} (at {}): {}".format(self.name, self.pos, self.string)
+
+    def __repr__(self):
+        return "%s('%s')" % (self.__class__.__name__, self)
+
+    def dict(self):
+        return {self.name: self.format_data()}
+
+    def format_data(self):
+        if self.is_list:
+            return [{item.key: item.value} for item in self.data]
+        else:
+            return {item.key: item.value for item in self.data}
+
+
+class Flow(object):
+    """The Flow class is a base class for other types of concrete flows
+    (such as OFproto Flows or DPIF Flows)
+
+    For each section provided, the object will have the following attributes
+    {section} will return the sections data in a formatted way
+    {section}_kv will return the sections data as a list of KeyValues
+
+    Args:
+        sections (list[Section]): list of sections that comprise the flow
+        orig (str): Original flow string
+        id (Any): Identifier
+    """
+
+    def __init__(self, sections, orig="", id=None):
+        self._sections = sections
+        self._orig = orig
+        self._id = id
+        for section in sections:
+            setattr(
+                self, section.name, self.section(section.name).format_data()
+            )
+            setattr(
+                self,
+                "{}_kv".format(section.name),
+                self.section(section.name).data,
+            )
+
+    def section(self, name):
+        """Return the section by name"""
+        return next(
+            (sect for sect in self._sections if sect.name == name), None
+        )
+
+    @property
+    def id(self):
+        """Return the Flow ID"""
+        return self._id
+
+    @property
+    def sections(self):
+        """Return the section by name"""
+        return self._sections
+
+    @property
+    def orig(self):
+        return self._orig
+
+    def dict(self):
+        """Returns the Flow information in a dictionary"""
+        flow_dict = {"orig": self.orig}
+        for section in self.sections:
+            flow_dict.update(section.dict())
+
+        return flow_dict