diff --git a/cvrpsep/Python.cpp b/cvrpsep/Python.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b52043932be6ec8911cbceb06a3e1a301c2bb26
--- /dev/null
+++ b/cvrpsep/Python.cpp
@@ -0,0 +1,321 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "Python.h"
+#include "cnstrmgr.h"
+#include "basegrph.h"
+#include "capsep.h"
+#include "mstarsep.h"
+#include "memmod.h"
+#include "brnching.h"
+#include "glmsep.h"
+#include "fcisep.h"
+#include "combsep.h"
+#include "htoursep.h"
+
+CnstrMgrPointer CMPExistingCuts = NULL;
+
+static PyObject *MyFunction( PyObject *self, PyObject *args ){
+  /* int x = PyObject_GetItem(args,0); 
+  PyTypeObject* t = o-> ob_type;
+  */
+  printf("coucou: %d\n", (int) PyTuple_Size(args));
+  PyObject* list = PyObject_GetItem(args,PyLong_FromLong(0));
+  PyObject* integer = PyObject_GetItem(list,PyLong_FromLong(0));
+  long integerC = PyLong_AsLong(integer);
+  printf("args[0]= %d\n",integerC);
+  Py_RETURN_NONE;
+}
+
+static void save_cuts(CnstrMgrPointer CutsCMP){
+  if ( ::CMPExistingCuts == NULL ) CMGR_CreateCMgr(&::CMPExistingCuts,100);
+  for (int i=0; i<CutsCMP->Size; i++) CMGR_MoveCnstr(CutsCMP,::CMPExistingCuts,i,0);
+}
+
+static void init_old_cuts_manager(){ if ( ::CMPExistingCuts == NULL ) CMGR_CreateCMgr(&::CMPExistingCuts,100); }
+
+static PyObject* column_generation( PyObject *self, PyObject *args){
+  /* will receive tuple consisting of:
+      number of customers 
+      Demand vector [(0),1,....n] of length NoOfCustomers+1 so that indexing is 1-based
+      capacity
+      number of edges
+      Edge X, Edge Head, Edge Tail : all 1-based and depot is in the last position
+      QMin (for the STI)
+  */
+  
+  int NoOfCustomers = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(0)));
+  PyObject* demand_list = PyObject_GetItem(args,PyLong_FromLong(1));
+  int CAP = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(2)));
+  int NoOfEdges = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(3)));
+  PyObject* x_list = PyObject_GetItem(args,PyLong_FromLong(4));
+  PyObject* head_list = PyObject_GetItem(args,PyLong_FromLong(5));
+  PyObject* tail_list = PyObject_GetItem(args,PyLong_FromLong(6));
+  int QMin = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(7)));
+  
+  double* EdgeX = MemGetDV(NoOfEdges+1);
+  int* EdgeHead = MemGetIV(NoOfEdges+1);
+  int* EdgeTail = MemGetIV(NoOfEdges+1);
+  int* Demand = MemGetIV(NoOfCustomers+2);
+
+  printf("Memory allocated\n");
+
+  for(int i=1; i<NoOfCustomers+1; i++){
+    Demand[i] = PyLong_AsLong( PyObject_GetItem( demand_list , PyLong_FromLong(i) ) );
+  }
+  Demand[NoOfCustomers+1] = 0;
+
+  for(int i=1; i<NoOfEdges+1; i++){
+    EdgeX[i] = PyFloat_AsDouble( PyObject_GetItem( x_list , PyLong_FromLong(i) ) ); 
+    EdgeHead[i] = PyLong_AsLong( PyObject_GetItem( head_list , PyLong_FromLong(i) ) );
+    EdgeTail[i] = PyLong_AsLong( PyObject_GetItem( tail_list , PyLong_FromLong(i) ) );
+    if(EdgeHead[i]<=0||EdgeHead[i]>NoOfCustomers+1) printf("Inaccurate head pointer %d\n", EdgeHead[i]);
+    if(EdgeTail[i]<=0||EdgeTail[i]>NoOfCustomers+1) printf("Inaccurate pointer %d\n", EdgeTail[i]);
+  }
+
+  printf("Python object scanned\n");
+ 
+  char IntegerAndFeasible;
+  double EpsForIntegrality = 0.0001;
+  double MaxCapViolation;
+  int Dim = 31;
+  int MaxNoOfCapCuts = 30;
+  CnstrMgrPointer CutsCMP;
+  CMGR_CreateCMgr(&CutsCMP,Dim);   
+
+  init_old_cuts_manager();
+
+  printf("Objects initialized\n");
+
+  //capacity cuts
+  CAPSEP_SeparateCapCuts(NoOfCustomers,Demand,CAP,NoOfEdges,EdgeTail,EdgeHead,EdgeX,::CMPExistingCuts,MaxNoOfCapCuts,EpsForIntegrality,&IntegerAndFeasible,&MaxCapViolation,CutsCMP);
+ 
+  if ( MaxCapViolation < 0.1 ){
+    //multistar cuts
+    int MaxNoOfMStarCuts = MaxNoOfCapCuts - CutsCMP->Size;
+    double MaxMStarViolation;
+    MSTARSEP_SeparateMultiStarCuts(NoOfCustomers,Demand,CAP,NoOfEdges,EdgeTail,EdgeHead,EdgeX,::CMPExistingCuts,MaxNoOfMStarCuts,&MaxMStarViolation,CutsCMP);
+  }
+
+  printf("Large multistar inequalities\n");
+  //Large Multistar inequalities
+  int* GLMCutList = MemGetIV(NoOfEdges+1);
+  int GLMCutListSize;
+  double GLMViolation;
+  GLMSEP_SeparateGLM(NoOfCustomers,Demand,CAP,NoOfEdges,EdgeTail,EdgeHead,EdgeX,GLMCutList,&GLMCutListSize,&GLMViolation);
+
+  printf("framed capacity inequalities\n");
+  // Framed capacity inequalities
+  double MaxFCIViolation;
+  int FCIMaxNoOfTreeNodes=100;
+  int MaxNoOfFCICuts = MaxNoOfCapCuts - CutsCMP->Size;
+  FCISEP_SeparateFCIs(NoOfCustomers, Demand, CAP, NoOfEdges, EdgeTail, EdgeHead, EdgeX, ::CMPExistingCuts, FCIMaxNoOfTreeNodes, MaxNoOfFCICuts, &MaxFCIViolation, CutsCMP);
+
+  printf("strenghtened comb inequalities\n");
+  // Stregthened comb inequalities
+  double MaxSCIViolation;
+  int MaxNoOfSCICuts = MaxNoOfCapCuts - CutsCMP->Size;
+  COMBSEP_SeparateCombs(NoOfCustomers, Demand, CAP, QMin, NoOfEdges, EdgeTail, EdgeHead, EdgeX, MaxNoOfSCICuts, &MaxSCIViolation, CutsCMP);
+
+  printf("hypotour inequalities\n");
+  // Hypotour inequalities
+  double MaxHTIViolation;
+  int MaxNoOfHTICuts = MaxNoOfCapCuts - CutsCMP->Size; 
+  printf("calling with max %d cuts\n", MaxNoOfHTICuts);
+  HTOURSEP_SeparateHTours(NoOfCustomers, Demand, CAP, NoOfEdges, EdgeTail, EdgeHead, EdgeX, ::CMPExistingCuts, MaxNoOfHTICuts, &MaxHTIViolation, CutsCMP);
+
+  //Retrieving the cuts
+
+  printf("Routines called, start retrieving cuts\n");
+  PyObject* Cuts = PyList_New(0);
+
+  //REMEMBER : in this cvrp library, lists are 1-based and the depot is coded as number n+1! 
+
+  //Capacity, multistar, framed and strengthened comb inequalities
+  for (int i=0; i<CutsCMP->Size; i++) {
+    PyObject* Cut = PyList_New(0);
+    if (CutsCMP->CPL[i]->CType == CMGR_CT_CAP){
+      PyList_Append(Cut,PyUnicode_FromString("cap"));
+      for (int j=1; j<=CutsCMP->CPL[i]->IntListSize; j++){
+        PyList_Append(Cut,PyLong_FromLong(CutsCMP->CPL[i]->IntList[j]));
+      }
+    }
+    if (CutsCMP->CPL[i]->CType == CMGR_CT_MSTAR){
+      PyList_Append(Cut,PyUnicode_FromString("mstar"));
+      //Nuclues
+      PyObject* Nucleus = PyList_New(0);      
+      for (int j=1; j<=CutsCMP->CPL[i]->IntListSize; j++){
+        PyList_Append(Nucleus,PyLong_FromLong(CutsCMP->CPL[i]->IntList[j]));
+      }
+      PyList_Append(Cut,Nucleus);
+      //Satellites
+      PyObject* Satellites = PyList_New(0);      
+      for (int j=1; j<=CutsCMP->CPL[i]->ExtListSize; j++){
+        PyList_Append(Satellites,PyLong_FromLong(CutsCMP->CPL[i]->ExtList[j]));
+      }
+      PyList_Append(Cut,Satellites);
+      //Connectors
+      PyObject* Connectors = PyList_New(0);      
+      for (int j=1; j<=CutsCMP->CPL[i]->CListSize; j++){
+        PyList_Append(Connectors,PyLong_FromLong(CutsCMP->CPL[i]->CList[j]));
+      }
+      PyList_Append(Cut,Connectors);
+      //Coefficients of the cut
+      PyList_Append(Cut,PyLong_FromLong(CutsCMP->CPL[i]->A));
+      PyList_Append(Cut,PyLong_FromLong(CutsCMP->CPL[i]->B));
+      PyList_Append(Cut,PyLong_FromLong(CutsCMP->CPL[i]->L));
+    }
+    if (CutsCMP->CPL[i]->CType == CMGR_CT_FCI){
+      PyList_Append(Cut,PyUnicode_FromString("fci"));
+      for (int j=1; j<=NoOfCustomers; j++) PyList_Append(Cut,PyLong_FromLong(0));
+      int MaxIdx = 0;
+      int MinIdx = 0;
+      for (int SubsetNr=1; SubsetNr<=CutsCMP->CPL[i]->ExtListSize; SubsetNr++){
+        MinIdx = MaxIdx+1;
+        MaxIdx = MinIdx + CutsCMP->CPL[i]->ExtList[SubsetNr] - 1;
+        for (int j=MinIdx; j<=MaxIdx; j++){
+          PyObject_SetItem(Cut,PyLong_FromLong(CutsCMP->CPL[i]->IntList[j]),PyLong_FromLong(SubsetNr));
+        }
+      }
+      PyList_Append(Cut,PyFloat_FromDouble(CutsCMP->CPL[i]->RHS));
+    }
+    if (CutsCMP->CPL[i]->CType == CMGR_CT_STR_COMB){
+      int MinIdx;
+      int MaxIdx;
+      PyList_Append(Cut,PyUnicode_FromString("sci"));
+      for (int j=1; j<=NoOfCustomers+1; j++) PyList_Append(Cut,PyList_New(0)); //ATTENTION : depot can be present in this cut! it's number is n+1 
+      int NoOfTeeth = CutsCMP->CPL[i]->Key;
+      for (int k=1; k<=CutsCMP->CPL[i]->IntListSize; k++){
+        PyList_Append(PyObject_GetItem(Cut,PyLong_FromLong(CutsCMP->CPL[i]->IntList[k])),PyLong_FromLong(0));
+      }
+      for (int t=1; t<=NoOfTeeth; t++){
+        MinIdx = CutsCMP->CPL[i]->ExtList[t];
+        if (t == NoOfTeeth) MaxIdx = CutsCMP->CPL[i]->ExtListSize;
+        else MaxIdx = CutsCMP->CPL[i]->ExtList[t+1] - 1;
+        for (int k=MinIdx; k<=MaxIdx; k++){
+          PyList_Append(PyObject_GetItem(Cut,PyLong_FromLong(CutsCMP->CPL[i]->ExtList[k])),PyLong_FromLong(t)); /* Node j is in tooth t */
+        }
+      }
+      PyList_Append(Cut,PyFloat_FromDouble(CutsCMP->CPL[i]->RHS));
+    }
+    if (CutsCMP->CPL[i]->CType == CMGR_CT_TWOEDGES_HYPOTOUR){
+      PyList_Append(Cut,PyUnicode_FromString("hti"));
+      PyList_Append(Cut,PyList_New(0)); //head
+      PyList_Append(Cut,PyList_New(0)); //tail
+      PyList_Append(Cut,PyList_New(0)); //coeff
+      for (int j=1; j<=CutsCMP->CPL[i]->IntListSize; j++){
+        PyList_Append(PyObject_GetItem(Cut,PyLong_FromLong(1)),PyLong_FromLong(CutsCMP->CPL[i]->IntList[j]));
+        PyList_Append(PyObject_GetItem(Cut,PyLong_FromLong(2)),PyLong_FromLong(CutsCMP->CPL[i]->ExtList[j]));
+        PyList_Append(PyObject_GetItem(Cut,PyLong_FromLong(3)),PyFloat_FromDouble(CutsCMP->CPL[i]->CoeffList[j]));
+      }
+      PyList_Append(Cut,PyFloat_FromDouble(CutsCMP->CPL[i]->RHS));
+    }
+    PyList_Append(Cuts,Cut);
+  }
+  
+  //Generalised large multistar inequalities
+  if (GLMCutListSize > 0){
+    PyObject* Cut = PyList_New(0);
+    PyList_Append(Cut,PyUnicode_FromString("glm"));
+    for(int i=1; i<=GLMCutListSize; i++){
+      PyList_Append(Cut,PyLong_FromLong(GLMCutList[i]));
+    }
+    PyList_Append(Cuts,Cut);
+  }
+
+  save_cuts(CutsCMP);
+  printf("Cuts retrieved, returning results\n");
+
+  return Cuts;
+}
+
+static PyObject* branching( PyObject *self, PyObject *args){
+  /* will receive tuple consisting of:
+      number of customers 
+      Demand vector [(0),1,....n] of length NoOfCustomers+1 so that indexing is 1-based
+      capacity
+      number of edges
+      Edge X, Edge Head, Edge Tail : all 1-based and depot is in the last position
+      
+  */
+  
+  int NoOfCustomers = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(0)));
+  PyObject* demand_list = PyObject_GetItem(args,PyLong_FromLong(1));
+  int CAP = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(2)));
+  int NoOfEdges = PyLong_AsLong(PyObject_GetItem(args,PyLong_FromLong(3)));
+  PyObject* x_list = PyObject_GetItem(args,PyLong_FromLong(4));
+  PyObject* head_list = PyObject_GetItem(args,PyLong_FromLong(5));
+  PyObject* tail_list = PyObject_GetItem(args,PyLong_FromLong(6));
+  
+  double* EdgeX = MemGetDV(NoOfEdges+1);
+  int* EdgeHead = MemGetIV(NoOfEdges+1);
+  int* EdgeTail = MemGetIV(NoOfEdges+1);
+  int* Demand = MemGetIV(NoOfCustomers+1);
+
+  for(int i=0; i<NoOfCustomers+1; i++){
+    Demand[i] = PyLong_AsLong( PyObject_GetItem( demand_list , PyLong_FromLong(i) ) );
+  }
+
+  for(int i=0; i<NoOfEdges+1; i++){
+    EdgeX[i] = PyFloat_AsDouble( PyObject_GetItem( x_list , PyLong_FromLong(i) ) ); 
+    EdgeHead[i] = PyLong_AsLong( PyObject_GetItem( head_list , PyLong_FromLong(i) ) );
+    EdgeTail[i] = PyLong_AsLong( PyObject_GetItem( tail_list , PyLong_FromLong(i) ) );
+  }
+
+  int MaxNoOfSets,SetNr;
+  double BoundaryTarget;
+  CnstrMgrPointer SetsCMP;
+  BoundaryTarget = 2.7;
+  MaxNoOfSets = NoOfCustomers;
+  CMGR_CreateCMgr(&SetsCMP,MaxNoOfSets);
+  BRNCHING_GetCandidateSets(NoOfCustomers,Demand,CAP,NoOfEdges,EdgeTail,EdgeHead,EdgeX,::CMPExistingCuts,BoundaryTarget,MaxNoOfSets,SetsCMP);
+
+  PyObject* Sets = PyList_New(0);
+  for (int i=0; i<SetsCMP->Size; i++){
+    PyObject* Set = PyList_New(0);
+    for (int j=1; j<=SetsCMP->CPL[i]->IntListSize; j++){
+      PyList_Append(Set,PyLong_FromLong(SetsCMP->CPL[i]->IntList[j]));
+    }
+    PyList_Append(Sets,Set);
+  }
+CMGR_FreeMemCMgr(&SetsCMP);
+return Sets;
+}
+
+static PyMethodDef module_methods[] = {
+   { "MyFunction", (PyCFunction)MyFunction, METH_VARARGS, "test function for using C/python API" },
+   { "column_generation", (PyCFunction)column_generation, METH_VARARGS, "returns the set of nodes that define a capacity cut" },
+   { "branching", (PyCFunction)branching, METH_VARARGS, "returns the set of nodes that define a constraint branching" },
+   { NULL, NULL, 0, NULL }
+};
+
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "cvrpsep", /* m_name */
+    "module to find cutting planes",      /* m_doc */
+    -1,                  /* m_size */
+    module_methods,    /* m_methods */
+    NULL,                /* m_reload */
+    NULL,                /* m_traverse */
+    NULL,                /* m_clear */
+    NULL,                /* m_free */
+  };
+
+static PyObject *
+moduleinit(void)
+{
+    PyObject *m;
+
+    m = PyModule_Create(&moduledef);
+
+    if (m == NULL)
+        return NULL;
+
+  return m;
+}
+
+PyMODINIT_FUNC
+    PyInit_cvrpsep(void)
+    {
+        return moduleinit();
+    }