diff --git a/.gitlab/ci/_global.gitlab-ci.yml b/.gitlab/ci/_global.gitlab-ci.yml
index aab5d745367d22052f82c6e3ef144680a822cd45..94e5658ff6adc8e07036d3d59ea39a68fbddc4bf 100644
--- a/.gitlab/ci/_global.gitlab-ci.yml
+++ b/.gitlab/ci/_global.gitlab-ci.yml
@@ -9,6 +9,14 @@ variables:
   GIT_SSL_NO_VERIFY: 1
   DEBIAN_FRONTEND: noninteractive
 
+# See https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines
+workflow:
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
+      when: never
+    - if: $CI_COMMIT_BRANCH
+
 default:
   image: nvidia/cuda:12.2.0-devel-ubuntu22.04
   before_script:
diff --git a/aidge_core/__init__.py b/aidge_core/__init__.py
index ad18a8ef1b23625dcb52951f52c43adc4222c997..c65dcc6cfc4be8825d1213854014718fb7170854 100644
--- a/aidge_core/__init__.py
+++ b/aidge_core/__init__.py
@@ -8,3 +8,4 @@ http://www.eclipse.org/legal/epl-2.0.
 SPDX-License-Identifier: EPL-2.0
 """
 from aidge_core.aidge_core import * # import so generated by PyBind
+from aidge_core.export import ExportNode
diff --git a/aidge_core/export/__init__.py b/aidge_core/export/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..00b44121d68af06171525fdf953bf50e53328421
--- /dev/null
+++ b/aidge_core/export/__init__.py
@@ -0,0 +1 @@
+from .node_export import *
diff --git a/aidge_core/export/node_export.py b/aidge_core/export/node_export.py
new file mode 100644
index 0000000000000000000000000000000000000000..980cb05a5814b7476d64757353e393ad6130218b
--- /dev/null
+++ b/aidge_core/export/node_export.py
@@ -0,0 +1,61 @@
+import aidge_core
+
+from abc import ABC, abstractmethod
+
+
+class ExportNode(ABC):
+    """Abstract class to interface node with export generation.
+    """
+
+    @abstractmethod
+    def __init__(self, aidge_node: aidge_core.Node) -> None:
+        """Create ExportNode and retieve attirubtes from ``aidge_node``:
+
+        - name: aidge Node name
+        - attributes: dictionnary of attributes of the aidge Operator linked to the node, attributes name follow aidge naming convention
+        - parameters: List of parameters node, order in the list is the same as the one defined by the aidge operator
+
+        """
+        super().__init__()
+        self.node = aidge_node
+        self.operator = aidge_node.get_operator()
+        self.name = self.node.name()
+        self.attributes = {} # Attributes are auto fetched from aidge operators
+        if isinstance(self.operator, aidge_core.Attributes):
+            for attr_name in self.operator.get_attrs_name():
+                self.attributes[attr_name] = self.operator.get_attr(attr_name)
+
+        # rename is_leaf ?
+        self.is_last = len(self.node.get_children()) == 0
+
+
+        self.inputs = []
+        self.outputs = []
+        self.inputs_dims = []
+        self.outputs_dims = []
+
+        for idx, parent_node in enumerate(self.node.get_parents()):
+            self.inputs.append(parent_node)
+            if parent_node is not None:
+                self.inputs_dims.append(self.operator.input(idx).dims())
+            else:
+                self.inputs_dims.append(None)
+
+        for idx, child_node in enumerate(self.node.get_children()):
+            self.outputs.append(child_node)
+        
+        # Dirty hot fix, change it quickly
+        self.outputs_dims.append(self.operator.output(0).dims())
+
+    @abstractmethod
+    def export(self, export_folder:str, list_configs:list):
+        """Define how to export the node definition.
+        """
+        pass
+
+    @abstractmethod
+    def forward(self, list_actions:list):
+        """Define how to generate code to perform a forward pass.
+        """
+        pass
+
diff --git a/python_binding/operator/pybind_GenericOperator.cpp b/python_binding/operator/pybind_GenericOperator.cpp
index 4cf4dae2234900722058d6555582c5b78900ab7d..241fc7f4a003f53de15a42859b078c54cc98b63a 100644
--- a/python_binding/operator/pybind_GenericOperator.cpp
+++ b/python_binding/operator/pybind_GenericOperator.cpp
@@ -27,7 +27,7 @@ void init_GenericOperator(py::module& m) {
     .def("compute_output_dims", &GenericOperator_Op::computeOutputDims)
     .def("set_compute_output_dims", &GenericOperator_Op::setComputeOutputDims, py::arg("computation_function"));
 
-    m.def("GenericOperator", &GenericOperator, py::arg("type"), py::arg("nbDataIn"), py::arg("nbIn"), py::arg("nbOut"),
+    m.def("GenericOperator", &GenericOperator, py::arg("type"), py::arg("nb_data_in"), py::arg("nb_in"), py::arg("nb_out"),
           py::arg("name") = "");
 }
 }  // namespace Aidge