diff --git a/SDK/C++/public/include/voltu/observer.hpp b/SDK/C++/public/include/voltu/observer.hpp
index 8f9cad3b74076de36662469829549ddbdd3595bc..03323b0793212d14bcc4f45f6112c1af33b30363 100644
--- a/SDK/C++/public/include/voltu/observer.hpp
+++ b/SDK/C++/public/include/voltu/observer.hpp
@@ -37,7 +37,7 @@ public:
 
 	PY_API virtual void setPose(const Eigen::Matrix4f &) = 0;
 
-	PY_API virtual voltu::FramePtr getFrame() = 0;
+	PY_API PY_RV_LIFETIME_PARENT virtual voltu::FramePtr getFrame() = 0;
 
 	PY_API virtual voltu::PropertyPtr property(voltu::ObserverProperty) = 0;
 };
diff --git a/SDK/C++/public/include/voltu/types/frame.hpp b/SDK/C++/public/include/voltu/types/frame.hpp
index baea806fc9db7d32c43f121bee7901d949378afc..adbd84c260984a52e43e25d185120341da5aa093 100644
--- a/SDK/C++/public/include/voltu/types/frame.hpp
+++ b/SDK/C++/public/include/voltu/types/frame.hpp
@@ -18,7 +18,7 @@ public:
 
 	PY_API PY_RV_LIFETIME_PARENT virtual voltu::PointCloudPtr getPointCloud(voltu::PointCloudFormat cloudfmt, voltu::PointFormat pointfmt) = 0;
 
-	virtual int64_t getTimestamp() = 0;
+	PY_API virtual int64_t getTimestamp() = 0;
 };
 
 typedef std::shared_ptr<Frame> FramePtr;
diff --git a/SDK/C++/public/python/CMakeLists.txt b/SDK/C++/public/python/CMakeLists.txt
index 20c4ce7c6697e30ffce941c74efbdf71f2f060e7..40bd39c8b388c667af935563da800a62910f0deb 100644
--- a/SDK/C++/public/python/CMakeLists.txt
+++ b/SDK/C++/public/python/CMakeLists.txt
@@ -31,3 +31,14 @@ target_include_directories(voltu_sdk_py PRIVATE .)
 
 target_link_libraries(voltu_sdk_py PUBLIC voltu_sdk)
 set_target_properties(voltu_sdk_py PROPERTIES OUTPUT_NAME voltu)
+
+enable_testing()
+find_package(Python3 COMPONENTS Interpreter)
+
+function(add_python_test TEST_NAME TEST_SCRIPT)
+    add_test(NAME ${TEST_NAME}
+        COMMAND Python3::Interpreter -m unittest ${TEST_SCRIPT}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+endfunction()
+
+add_python_test(test_load tests/test_load.py)
diff --git a/SDK/C++/public/python/README.md b/SDK/C++/public/python/README.md
index a1a955eba963313d9d1f1d2eaca1466715fc070d..a5cd30d6d96bab1733841acf5bca73947d6655f0 100644
--- a/SDK/C++/public/python/README.md
+++ b/SDK/C++/public/python/README.md
@@ -1,7 +1,7 @@
 # Python API generator
 
 Dependencies
- * python3-ply (cpp header parser)
+ * python3-ply (build only)
 
 Build system uses Pybind11 to generate a python module. Most of the bindings are
 automatically generated by gen.py script which is automatically called by CMake
@@ -34,3 +34,4 @@ build. Several (empty) macros are used in headers to annoate Python API details.
  * Static members
  * Constructors
  * Automatic documentation (Doxygen)
+ * Generator does not verify that shared_ptr<> is used consistently/correctly
diff --git a/SDK/C++/public/python/tests/__init__.py b/SDK/C++/public/python/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/SDK/C++/public/python/tests/test_load.py b/SDK/C++/public/python/tests/test_load.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e5131d4d4299af3ac116f3585de9403b6ee2f9d
--- /dev/null
+++ b/SDK/C++/public/python/tests/test_load.py
@@ -0,0 +1,12 @@
+import unittest
+
+class LoadLibrary(unittest.TestCase):
+
+    def test_get_instance(self):
+        import voltu
+        self.assertIsNotNone(voltu.instance())
+        # second call to instance() returns None
+        #self.assertIsNotNone(voltu.instance())
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/SDK/C++/public/python/types/image.hpp b/SDK/C++/public/python/types/image.hpp
index 15cd41034f8cd748dd9413793e1bbe9ce8825496..8bbeae3e9730091c79e92fa91f0738be026456dd 100644
--- a/SDK/C++/public/python/types/image.hpp
+++ b/SDK/C++/public/python/types/image.hpp
@@ -21,6 +21,7 @@ public:
     PYBIND11_TYPE_CASTER(voltu::ImageData, _("Image"));
 
     bool load(py::handle src, bool convert) {
+        // TODO: C++ api should copy or otherwise take (shared) ownership
         throw std::runtime_error("ImageData conversion python->c++ not supported");
         return true;
     }