diff --git a/new_python/CMakeLists.txt b/new_python/CMakeLists.txt
index f9b226d2b97e682a0de7762e2d664c93c200e9ef..78e047c3a4a52e35ed7a0240a6d7012f1690ef10 100644
--- a/new_python/CMakeLists.txt
+++ b/new_python/CMakeLists.txt
@@ -14,10 +14,14 @@ if(NOT pybind11_POPULATED)
     add_subdirectory(${pybind11_SOURCE_DIR} ${pybind11_BINARY_DIR})
 endif()
 
+# the mpi version
+if(MPI_FOUND)
 pybind11_add_module(pygio_new genericio.cpp)
 set_target_properties(pygio_new PROPERTIES OUTPUT_NAME pygio)
-if(MPI_FOUND)
-    target_link_libraries(pygio_new PRIVATE genericio_mpi)
-else()
-    target_link_libraries(pygio_new PRIVATE genericio)
-endif()
\ No newline at end of file
+target_link_libraries(pygio_new PRIVATE genericio_mpi)
+endif()
+
+# The no-mpi version
+pybind11_add_module(pygio_new_nompi genericio.cpp)
+set_target_properties(pygio_new_nompi PROPERTIES OUTPUT_NAME pygio_nompi)
+target_link_libraries(pygio_new_nompi PRIVATE genericio)
\ No newline at end of file
diff --git a/new_python/README.md b/new_python/README.md
index 6c88db9eeb55aa7f03589b421bb326dc3677a9fc..b14a2ced5af8afab9f93e30cb85a18e8ce19bd1d 100644
--- a/new_python/README.md
+++ b/new_python/README.md
@@ -136,4 +136,20 @@ rank 4 read 70625 elements
 rank 5 read 70625 elements
 rank 6 read 70625 elements
 rank 7 read 70625 elements
-```
\ No newline at end of file
+```
+
+### Force the non-MPI version to be imported
+
+Some clusters prevent the loading of MPI libraries on the login nodes. In order
+to still be able to use the same `pygio` on the login nodes, the non-MPI library
+can be loaded by setting the `GENERICIO_NO_MPI` environment variable before
+importing `pygio`:
+
+```python
+import os
+os.environ['GENERICIO_NO_MPI'] = 'True'
+import pygio
+```
+
+A warning will be printed that the writing capabilities of genericio are not
+available in this mode.
\ No newline at end of file
diff --git a/new_python/genericio.cpp b/new_python/genericio.cpp
index e8ad1d960a7a85a9b13e36623f35c8d8315dc23a..59cf08b5e5b50c2019634cd07ba18cfaf3b6df1d 100644
--- a/new_python/genericio.cpp
+++ b/new_python/genericio.cpp
@@ -136,20 +136,37 @@ private:
   std::vector<gio::GenericIO::VariableInfo> variables;
 };
 
-std::map<std::string, py::array> read_genericio(std::string filename, std::optional<std::vector<std::string>> var_names, PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX, PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute, bool rebalance_source_ranks=false) {
+std::map<std::string, py::array> read_genericio(
+    std::string filename, 
+    std::optional<std::vector<std::string>> var_names, 
+    PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX, 
+    PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute, 
+    bool rebalance_source_ranks=false
+  ) {
   PyGenericIO reader(filename, method, redistribute);
+#ifndef GENERICIO_NO_MPI
   if(rebalance_source_ranks)
     reader.rebalanceSourceRanks();
+#endif
   return reader.read(var_names);
 }
 
-void inspect_genericio(std::string filename, PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX, PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute) {
+void inspect_genericio(
+    std::string filename, 
+    PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX, 
+    PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
+  ) {
   PyGenericIO reader(filename, method, redistribute);
   reader.inspect();
 }
 
 #ifndef GENERICIO_NO_MPI
-void write_genericio(std::string filename, std::map<std::string, py::array> variables, std::array<double, 3> phys_scale, std::array<double, 3> phys_origin, PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX) {
+void write_genericio(
+    std::string filename, 
+    std::map<std::string, py::array> variables, 
+    std::array<double, 3> phys_scale, std::array<double, 3> phys_origin, 
+    PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX
+  ) {
   // check data integrity, find particle count
   int64_t particle_count = -1;
   for(auto const& [name, data]: variables) {
@@ -193,9 +210,13 @@ void write_genericio(std::string filename, std::map<std::string, py::array> vari
 }
 #endif
 
+
+#ifdef GENERICIO_NO_MPI
+PYBIND11_MODULE(pygio_nompi, m) {
+  m.doc() = "genericio python module (no MPI support)";
+#else  // GENERICIO_NO_MPI
 PYBIND11_MODULE(pygio, m) {
-  m.doc() = "genericio python module";
-#ifndef GENERICIO_NO_MPI
+  m.doc() = "genericio python module (with MPI support)";
   m.def("_init_mpi", [](){
     int initialized;
     MPI_Initialized(&initialized);
@@ -218,7 +239,11 @@ PYBIND11_MODULE(pygio, m) {
     .value("MismatchDisallowed", PyGenericIO::MismatchBehavior::MismatchDisallowed)
     .value("MismatchRedistribute", PyGenericIO::MismatchBehavior::MismatchRedistribute);
 
-  pyGenericIO.def(py::init<std::string, PyGenericIO::FileIO, PyGenericIO::MismatchBehavior>(), py::arg("filename"), py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX, py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute)
+  pyGenericIO.def(
+      py::init<std::string, PyGenericIO::FileIO, PyGenericIO::MismatchBehavior>(), 
+        py::arg("filename"), 
+        py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX, 
+        py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute)
       .def("inspect", &PyGenericIO::inspect, "Print variable infos and size of GenericIO file")
       .def("get_variables", &PyGenericIO::get_variables, "Get a list of VariableInformations defined in the GenericIO file")
       .def("read_num_elems", (size_t (PyGenericIO::*)(int))(&PyGenericIO::readNumElems), py::arg("eff_rank")=-1)
@@ -227,7 +252,10 @@ PYBIND11_MODULE(pygio, m) {
       .def("read_phys_scale", &PyGenericIO::read_phys_scale)
       .def("read", &PyGenericIO::read, py::arg("variables")=nullptr)
       .def("get_source_ranks", &PyGenericIO::getSourceRanks)
-      .def("rebalance_source_ranks", &PyGenericIO::rebalanceSourceRanks);
+#ifndef GENERICIO_NO_MPI
+      .def("rebalance_source_ranks", &PyGenericIO::rebalanceSourceRanks)
+#endif
+      ;
 
   py::class_<gio::GenericIO::VariableInfo>(pyGenericIO, "VariableInfo")
       .def_readonly("name", &gio::GenericIO::VariableInfo::Name)
@@ -238,9 +266,29 @@ PYBIND11_MODULE(pygio, m) {
         return std::string("<PyGenericIO.VariableInfo type=") +
                (vi.IsFloat ? "float" : "int") + " name='" + vi.Name + "'>";
       });
-  m.def("read_genericio", &read_genericio, py::arg("filename"), py::arg("variables")=nullptr, py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX, py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute, py::arg("rebalance_sourceranks")=false, py::return_value_policy::move);
-  m.def("inspect_genericio", &inspect_genericio, py::arg("filename"), py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX, py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
+
+  m.def("read_genericio", &read_genericio, 
+        py::arg("filename"), 
+        py::arg("variables")=nullptr, 
+        py::kw_only(),
+        py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX, 
+        py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute, 
+        py::arg("rebalance_sourceranks")=false, 
+        py::return_value_policy::move);
+
+  m.def("inspect_genericio", &inspect_genericio, 
+        py::arg("filename"), 
+        py::kw_only(),
+        py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX, 
+        py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
+
 #ifndef GENERICIO_NO_MPI
-  m.def("write_genericio", &write_genericio, py::arg("filename"), py::arg("variables"), py::arg("phys_scale"), py::arg("phys_origin") = std::array<double, 3>({0., 0., 0.}), py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX);
+  m.def("write_genericio", &write_genericio, 
+        py::arg("filename"), 
+        py::arg("variables"), 
+        py::arg("phys_scale"), 
+        py::arg("phys_origin") = std::array<double, 3>({0., 0., 0.}), 
+        py::kw_only(),
+        py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX);
 #endif
 }
diff --git a/new_python/pygio/__init__.py b/new_python/pygio/__init__.py
index d5707c6a0a3e58df16835037b8ea8667db4001de..17ea2496000907a2e0df98cf6f9f13f8129b320b 100644
--- a/new_python/pygio/__init__.py
+++ b/new_python/pygio/__init__.py
@@ -1,9 +1,20 @@
 from __future__ import print_function
-from . import pygio as _pygio
+import os
 
-try:
-    _pygio._init_mpi()
-except:
-    print("WARNING: The pygio module has been compiled without MPI support. Writing GenericIO files not supported.")
+_GENERICIO_NO_MPI = False
+if 'GENERICIO_NO_MPI' in os.environ:
+    _GENERICIO_NO_MPI = os.environ['GENERICIO_NO_MPI'].lower() in ['true', 'yes', 'y']
 
-from .pygio import *
\ No newline at end of file
+if _GENERICIO_NO_MPI:
+    print("WARNING: the pygio module without MPI support has been loaded (due to the GENERICIO_NO_MPI env variable). Writing GenericIO files not supported.")
+    from .pygio_nompi import *
+
+else:
+    # try to load the MPI library (or the no-mpi library, in case of missing MPI during compilation)
+    from . import pygio as _pygio
+    try:
+        _pygio._init_mpi()
+    except:
+        print("WARNING: The pygio module has been compiled without MPI support. Writing GenericIO files not supported.")
+
+    from .pygio import *
\ No newline at end of file