diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 1ab9e95c09d022f31be16bf8fc7eda5099536456..7e5b02f3e4e8d14d6864761022b920bc32706faa 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -16,6 +16,7 @@ add_subdirectory(pybind11)
 
 # The Python library. MODULE will make a Python-exclusive model.
 add_library(pyarb MODULE
+    config.cpp
     context.cpp
     exception.cpp
     mpi.cpp
diff --git a/python/config.cpp b/python/config.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..50fc788e7d3ca23fcd2d23cc38cdbbe3bec0e08e
--- /dev/null
+++ b/python/config.cpp
@@ -0,0 +1,12 @@
+#include <pybind11/pybind11.h>
+
+#include "config.hpp"
+
+namespace pyarb {
+
+void register_config(pybind11::module &m) {
+
+    m.def("config", &config, "Get Arbor's configuration.")
+     .def("print_config", [](const pybind11::dict& d){return print_config(d);}, "Print Arbor's configuration.");
+}
+} // namespace pyarb
diff --git a/python/config.hpp b/python/config.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..57cf085851374b10f4997035ca2858c8d27a3374
--- /dev/null
+++ b/python/config.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <arbor/version.hpp>
+
+#include <sstream>
+#include <iomanip>
+#include <ios>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace pyarb {
+
+// Create and return a dictionary
+pybind11::dict config() {
+    pybind11::dict dict;
+    #ifdef ARB_MPI_ENABLED
+        dict[pybind11::str("mpi")]     = pybind11::bool_(true);
+    #else
+        dict[pybind11::str("mpi")]     = pybind11::bool_(false);
+    #endif
+    #ifdef ARB_WITH_MPI4PY
+        dict[pybind11::str("mpi4py")]  = pybind11::bool_(true);
+    #else
+        dict[pybind11::str("mpi4py")]  = pybind11::bool_(false);
+    #endif
+    #ifdef ARB_WITH_GPU
+        dict[pybind11::str("gpu")]     = pybind11::bool_(true);
+    #else
+        dict[pybind11::str("gpu")]     = pybind11::bool_(false);
+    #endif
+        dict[pybind11::str("version")] = pybind11::str(ARB_VERSION);
+    return dict;
+}
+
+void print_config(const pybind11::dict &d) {
+    std::stringstream s;
+    s << "Arbor's configuration:" << std::endl;
+
+    for (auto x: d) {
+        s << "     "
+          << std::left << std::setw(7) << x.first << ": "
+          << std::right << std::setw(10) << x.second << "\n";
+    }
+
+    pybind11::print(s.str());
+}
+} // namespace pyarb
diff --git a/python/pyarb.cpp b/python/pyarb.cpp
index 8f3be8f09b89bb44d06816b212392dc051c9ef74..a4a897c556b3b9b5381e670566d3fd4eef8252d1 100644
--- a/python/pyarb.cpp
+++ b/python/pyarb.cpp
@@ -6,18 +6,19 @@
 // types and functions to be exposed to Python.
 namespace pyarb {
 
+void register_config(pybind11::module& m);
 void register_contexts(pybind11::module& m);
 void register_queryenvvars(pybind11::module& m);
 #ifdef ARB_MPI_ENABLED
 void register_mpi(pybind11::module& m);
 #endif
-
 }
 
 PYBIND11_MODULE(arbor, m) {
     m.doc() = "arbor: Python bindings for Arbor.";
     m.attr("__version__") = ARB_VERSION;
 
+    pyarb::register_config(m);
     pyarb::register_contexts(m);
     pyarb::register_queryenvvars(m);
     #ifdef ARB_MPI_ENABLED
diff --git a/python/strings.cpp b/python/strings.cpp
index abcb06499d4930996452874c355e4e3a603c32a7..f61e7c76b5c41cb97f4636ce267dfbc7656c1dec 100644
--- a/python/strings.cpp
+++ b/python/strings.cpp
@@ -7,6 +7,18 @@
 
 namespace pyarb {
 
+std::string context_string(const arb::context& c) {
+    std::stringstream s;
+    const bool gpu = arb::has_gpu(c);
+    const bool mpi = arb::has_mpi(c);
+    s << "<context: threads " << arb::num_threads(c)
+      << ", gpu " << (gpu? "yes": "None") 
+      << ", distributed " << (mpi? "MPI": "Local")
+      << " ranks " << arb::num_ranks(c)
+      << ">";
+    return s.str();
+}
+
 std::string proc_allocation_string(const arb::proc_allocation& a) {
     std::stringstream s;
     s << "<hardware resource allocation: threads " << a.num_threads << ", gpu ";
@@ -20,15 +32,4 @@ std::string proc_allocation_string(const arb::proc_allocation& a) {
     return s.str();
 }
 
-std::string context_string(const arb::context& c) {
-    std::stringstream s;
-    const bool gpu = arb::has_gpu(c);
-    const bool mpi = arb::has_mpi(c);
-    s << "<context: threads " << arb::num_threads(c)
-      << ", gpu " << (gpu? "yes": "None")
-      << ", distributed " << (mpi? "MPI": "Local")
-      << " ranks " << arb::num_ranks(c)
-      << ">";
-    return s.str();
-}
 } // namespace pyarb