diff --git a/ale/__init__.py b/ale/__init__.py
index b649ee82414e20bfe6ebad469da86f654dae8f38..f2d46ca2575f049a9d174327036200f3c0d83b73 100644
--- a/ale/__init__.py
+++ b/ale/__init__.py
@@ -1,2 +1,2 @@
 from . import drivers
-from .drivers import load, loads
+from .drivers import load
diff --git a/ale/drivers/__init__.py b/ale/drivers/__init__.py
index a0f027848f8b35437a862264999d046042530017..7f0056e8760e28b403b24646a3031f790bc94bed 100644
--- a/ale/drivers/__init__.py
+++ b/ale/drivers/__init__.py
@@ -20,6 +20,9 @@ __driver_modules__ = [importlib.import_module('.'+m, package='ale.drivers') for
 drivers = dict(chain.from_iterable(inspect.getmembers(dmod, lambda x: inspect.isclass(x) and "_driver" in x.__module__) for dmod in __driver_modules__))
 
 def load(label):
+    """
+    Load label from
+    """
     for name, driver in drivers.items():
         try:
             print("TRYING:", driver)
@@ -32,19 +35,3 @@ def load(label):
             import traceback
             traceback.print_exc()
     raise Exception('No Such Driver for Label')
-
-def loads(label):
-    class NumpyEncoder(json.JSONEncoder):
-        def default(self, obj):
-            if isinstance(obj, np.ndarray):
-                return obj.tolist()
-            return json.JSONEncoder.default(self, obj)
-
-    def json_serial(obj):
-        """JSON serializer for objects not serializable by default json code"""
-        if isinstance(obj, (datetime, date)):
-            return obj.isoformat()
-
-    with load(label) as o:
-        s = json.dumps(o.to_dict(), cls=NumpyEncoder, default=json_serial)
-    return s
diff --git a/ale/drivers/base.py b/ale/drivers/base.py
index 050ed24852cb85894f4c9ae2538caa5decbf8cb3..57e8d3758dde10b0ad6e1598fba943b019b3fd09 100644
--- a/ale/drivers/base.py
+++ b/ale/drivers/base.py
@@ -7,8 +7,18 @@ class Driver():
     """
     Base class for all Drivers.
 
+    Attributes
+    ----------
+    _file : str
+            Reference to file path to be used by mixins for opening.
     """
     def __init__(self, file):
+        """
+        Parameters
+        ----------
+        file : str
+               path to file to be parsed
+        """
         self._file = file
 
     def __str__(self):
@@ -29,6 +39,15 @@ class Driver():
 class LineScanner(Driver):
     @property
     def name_model(self):
+        """
+        Returns Key used to define the sensor type. Primarily
+        used for generating camera models.
+
+        Returns
+        -------
+        : str
+          USGS Frame model
+        """
         return "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL"
 
     @property
@@ -50,8 +69,10 @@ class LineScanner(Driver):
     @property
     def line_scan_rate(self):
         """
-        In the form: [start_line, line_time, exposure_duration]
-        The form below is for a fixed rate line scanner.
+        Returns
+        -------
+        : list
+          2d list of scan rates in the form: [[start_line, line_time, exposure_duration], ...]
         """
         return [[float(self.starting_detector_line), self.t0_ephemeris, self.line_exposure_duration]]
 
@@ -69,6 +90,15 @@ class LineScanner(Driver):
 class Framer(Driver):
     @property
     def name_model(self):
+        """
+        Returns Key used to define the sensor type. Primarily
+        used for generating camera models.
+
+        Returns
+        -------
+        : str
+          USGS Frame model
+        """
         return "USGS_ASTRO_FRAME_SENSOR_MODEL"
 
     @property
@@ -87,6 +117,15 @@ class Framer(Driver):
 
 
 class PDS3():
+    """
+    Mixin for reading from PDS3 Labels.
+
+    Attributes
+    ----------
+    _label : PVLModule
+             Dict-like object with PVL keys
+
+    """
     def _compute_ephemerides(self):
         """
         Helper function to pull position and velocity in one pass
@@ -117,6 +156,14 @@ class PDS3():
 
     @property
     def label(self):
+        """
+        Loads a PVL from from the _file attribute.
+
+        Returns
+        -------
+        : PVLModule
+          Dict-like object with PVL keys
+        """
         if not hasattr(self, "_label"):
             if isinstance(self._file, pvl.PVLModule):
                 self._label = label
@@ -157,6 +204,17 @@ class PDS3():
 
     @property
     def target_name(self):
+        """
+        Returns an target name for unquely identifying the instrument, but often
+        piped into Spice Kernels to acquire Ephermis data from Spice. Therefore they
+        the same ID the Spice expects in bodvrd calls.
+
+        Returns
+        -------
+        : str
+          target name
+        """
+
         return self.label['TARGET_NAME']
 
     @property
@@ -203,6 +261,15 @@ class PDS3():
 
     @property
     def spacecraft_name(self):
+        """
+        Spacecraft name used in various Spice calls to acquire
+        ephemeris data.
+
+        Returns
+        -------
+        : str
+          Spacecraft name
+        """
         return self.label['MISSION_NAME']
 
     @property
@@ -223,6 +290,7 @@ class PDS3():
 
 
 class Spice():
+
     @property
     def metakernel(self):
         pass
@@ -246,18 +314,42 @@ class Spice():
 
     @property
     def odtx(self):
-        return spice.gdpool('INS{}_OD_T_X'.format(self.ikid),0, 10)
+        """
+        Returns
+        -------
+        : list
+          Optical distortion x coefficients
+        """
+        return spice.gdpool('INS{}_OD_T_X'.format(self.ikid),0, 10).tolist()
 
     @property
     def odty(self):
-        return spice.gdpool('INS{}_OD_T_Y'.format(self.ikid), 0, 10)
+        """
+        Returns
+        -------
+        : list
+          Optical distortion y coefficients
+        """
+        return spice.gdpool('INS{}_OD_T_Y'.format(self.ikid), 0, 10).tolist()
 
     @property
     def odtk(self):
-        return spice.gdpool('INS{}_OD_K'.format(self.ikid),0, 3)
+        """
+        Returns
+        -------
+        : list
+          Radial distortion coefficients
+        """
+        return spice.gdpool('INS{}_OD_K'.format(self.ikid),0, 3).tolist()
 
     @property
     def ikid(self):
+        """
+        Returns
+        -------
+        : int
+          Naif ID used to for indentifying the instrument in Spice kernels
+        """
         return spice.bods2c(self.instrument_id)
 
     @property
@@ -266,11 +358,11 @@ class Spice():
 
     @property
     def focal2pixel_lines(self):
-        return spice.gdpool('INS{}_ITRANSL'.format(self.fikid), 0, 3)
+        return list(spice.gdpool('INS{}_ITRANSL'.format(self.fikid), 0, 3))
 
     @property
     def focal2pixel_samples(self):
-        return spice.gdpool('INS{}_ITRANSS'.format(self.fikid), 0, 3)
+        return list(spice.gdpool('INS{}_ITRANSS'.format(self.fikid), 0, 3))
 
     @property
     def focal_length(self):
@@ -278,11 +370,23 @@ class Spice():
 
     @property
     def semimajor(self):
+        """
+        Returns
+        -------
+        : double
+          Semimajor axis of the target body
+        """
         rad = spice.bodvrd(self.target_name, 'RADII', 3)
         return rad[1][1]
 
     @property
     def semiminor(self):
+        """
+        Returns
+        -------
+        : double
+          Semiminor axis of the target body
+        """
         rad = spice.bodvrd(self.target_name, 'RADII', 3)
         return rad[1][0]
 
@@ -312,6 +416,7 @@ class Spice():
 
     @property
     def sensor_position(self):
+
         if not hasattr(self, '_sensor_position'):
             self._compute_ephemerides()
         return self._sensor_position.tolist()
@@ -395,14 +500,35 @@ class Isis3():
 
     @property
     def spacecraft_name(self):
+        """
+        Spacecraft name used in various Spice calls to acquire
+        ephemeris data.
+
+        Returns
+        -------
+        : str
+          Spacecraft name
+        """
         return self.label['IsisCube']['Instrument']['SpacecraftName']
 
     @property
     def image_lines(self):
+        """
+        Returns
+        -------
+        : int
+          Number of lines in image
+        """
         return self.label['IsisCube']['Core']['Dimensions']['Lines']
 
     @property
     def image_samples(self):
+        """
+        Returns
+        -------
+        : int
+          Number of samples in image
+        """
         return self.label['IsisCube']['Core']['Dimensions']['Samples']
 
     @property
@@ -411,6 +537,15 @@ class Isis3():
 
     @property
     def target_name(self):
+        """
+        Target name used in various Spice calls to acquire
+        target specific ephemeris data.
+
+        Returns
+        -------
+        : str
+          Target name
+        """
         return self.label['IsisCube']['Instrument']['TargetName']
 
     @property
diff --git a/ale/drivers/cassini_driver.py b/ale/drivers/cassini_driver.py
index ebbb670fb19a8ebd17cecbda0253b34789cfeb19..c584bd197756f91b387ecb4d8e248f7007ab6c29 100644
--- a/ale/drivers/cassini_driver.py
+++ b/ale/drivers/cassini_driver.py
@@ -11,6 +11,9 @@ from ale.drivers import keys
 
 
 class CassiniISS(Framer):
+    """
+    Cassini mixin class for defining snowflake Spice calls. 
+    """
     id_lookup = {
         "ISSNA" : "CASSINI_ISS_NAC",
         "ISSWA" : "CASSINI_ISS_WAC"
@@ -20,6 +23,14 @@ class CassiniISS(Framer):
 
     @property
     def metakernel(self):
+        """
+        Returns latest instrument metakernels
+
+        Returns
+        -------
+        : string
+          Path to latest metakernel file
+        """
         metakernel_dir = config.cassini
         mks = sorted(glob(os.path.join(metakernel_dir,'*.tm')))
         if not hasattr(self, '_metakernel'):
@@ -30,6 +41,16 @@ class CassiniISS(Framer):
 
     @property
     def instrument_id(self):
+        """
+        Returns an instrument id for unquely identifying the instrument, but often
+        also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
+        the same ID the Spice expects in bods2c calls.
+
+        Returns
+        -------
+        : str
+          instrument id
+        """
         return self.id_lookup[self.label['INSTRUMENT_ID']]
 
     @property
@@ -38,6 +59,10 @@ class CassiniISS(Framer):
 
     @property
     def spacecraft_name(self):
+        """
+        Spacecraft name used in various Spice calls to acquire
+        ephemeris data.
+        """
         return 'CASSINI'
 
     @property
diff --git a/ale/drivers/lro_driver.py b/ale/drivers/lro_driver.py
index 5654f672f993a8779a17326cf8af1713b90fc8a9..a97cab4507a1188c918ea3783ed8bd4851c73320 100644
--- a/ale/drivers/lro_driver.py
+++ b/ale/drivers/lro_driver.py
@@ -11,24 +11,58 @@ from ale.drivers import keys
 
 
 class LrocSpice(Spice, LineScanner):
+    """
+    Lroc mixin class for defining snowflake Spice calls.
+    """
     required_keys = keys.base | keys.linescanner
 
     @property
     def metakernel(self):
+        """
+        Returns latest instrument metakernels
+
+        Returns
+        -------
+        : string
+          Path to latest metakernel file
+        """
         metakernels = get_metakernels(years=self.start_time.year, missions='lro', versions='latest')
         self._metakernel = metakernels['data'][0]['path']
         return self._metakernel
 
     @property
     def spacecraft_name(self):
+        """
+        Spacecraft name used in various Spice calls to acquire
+        ephemeris data.
+
+        Returns
+        -------
+        : str
+          Spacecraft name
+        """
         return "LRO"
 
 
-class LroPds3Driver(PDS3, LrocSpice):
+class LrocPds3Driver(PDS3, LrocSpice):
+    """
+    Driver for reading Lroc labels. Requires a Spice mixin to acquire addtional
+    ephemeris and instrument data located exclusively in spice kernels.
+    """
+
     @property
     def instrument_id(self):
         """
+        Returns an instrument id for uniquely identifying the instrument, but often
+        also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
+        the same ID the Spice expects in bods2c calls.
+
         Ignores Wide Angle for now
+
+        Returns
+        -------
+        : str
+          instrument id
         """
 
         instrument = self.label.get("INSTRUMENT_ID")
diff --git a/ale/drivers/mdis_driver.py b/ale/drivers/mdis_driver.py
index 89770feb9eb99448e6acb01d409a3daa8e3f70d5..1091f8a6e01e2b9e040109387dbd29127b69a10d 100644
--- a/ale/drivers/mdis_driver.py
+++ b/ale/drivers/mdis_driver.py
@@ -11,6 +11,12 @@ from ale.drivers import keys
 
 
 class MdisSpice(Spice, Framer):
+    """
+    MDIS mixin class for defining snowflake Spice calls. Since MDIS has unique
+    Spice keys, those are defined here as an intermediate mixin for MDIS drivers
+    that rely on Spice kernels.
+    """
+
     id_lookup = {
         'MDIS-WAC': 'MSGR_MDIS_WAC',
         'MDIS-NAC':'MSGR_MDIS_NAC',
@@ -22,6 +28,14 @@ class MdisSpice(Spice, Framer):
 
     @property
     def metakernel(self):
+        """
+        Returns latest instrument metakernels
+
+        Returns
+        -------
+        : string
+          Path to latest metakernel file
+        """
         metakernel_dir = config.mdis
         mks = sorted(glob(os.path.join(metakernel_dir,'*.tm')))
         if not hasattr(self, '_metakernel'):
@@ -33,10 +47,20 @@ class MdisSpice(Spice, Framer):
     @property
     def focal_length(self):
         """
+        Computes Focal Length from Kernels
+
+        MDIS has tempature dependant focal lengh and coefficients need to
+        be acquired from IK Spice kernels (coeff describe focal length as a
+        function of tempature). Focal plane temps are acquired from a PDS3 label.
+
+        Returns
+        -------
+        : double
+          focal length in meters
         """
         coeffs = spice.gdpool('INS{}_FL_TEMP_COEFFS '.format(self.fikid), 0, 5)
 
-        # reverse coeffs, mdis coeffs are listed a_0, a_1, a_2 ... a_n where
+        # reverse coeffs, MDIS coeffs are listed a_0, a_1, a_2 ... a_n where
         # numpy wants them a_n, a_n-1, a_n-2 ... a_0
         f_t = np.poly1d(coeffs[::-1])
 
@@ -45,34 +69,78 @@ class MdisSpice(Spice, Framer):
 
     @property
     def starting_detector_sample(self):
+        """
+        Returns starting detector sample quired from Spice Kernels.
+
+        Returns
+        -------
+        : int
+          starting detector sample
+        """
         return int(spice.gdpool('INS{}_FPUBIN_START_SAMPLE'.format(self.ikid), 0, 1)[0])
 
     @property
     def starting_detector_line(self):
+        """
+        Returns starting detector sample acquired from Spice Kernels.
+
+        Returns
+        -------
+        : string
+          Path to latest metakernel file
+        """
         return int(spice.gdpool('INS{}_FPUBIN_START_LINE'.format(self.ikid), 0, 1)[0])
 
 
 class MdisPDS3Driver(PDS3, MdisSpice):
+    """
+    Driver for reading MDIS PDS3 labels. Requires a Spice mixin to acquire addtional
+    ephemeris and instrument data located exclusively in spice kernels.
+    """
     @property
     def instrument_id(self):
+        """
+        Returns an instrument id for unquely identifying the instrument, but often
+        also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
+        the same ID the Spice expects in bods2c calls.
+
+        Returns
+        -------
+        : str
+          instrument id
+        """
         return self.id_lookup[self.label['INSTRUMENT_ID']]
 
 
 class MdisIsis3Driver(Isis3, MdisSpice):
-    @property
-    def metakernel(self):
-        metakernel_dir = config.mdis
-        mks = sorted(glob(os.path.join(metakernel_dir,'*.tm')))
-        if not hasattr(self, '_metakernel'):
-            for mk in mks:
-                if str(self.start_time.year) in os.path.basename(mk):
-                    self._metakernel = mk
-        return self._metakernel
+    """
+    Driver for reading MDIS ISIS3 Labels. These are Labels that have been ingested
+    into ISIS from PDS EDR images but have not been spiceinit'd yet.
+    """
 
     @property
     def instrument_id(self):
+        """
+        Returns an instrument id for unquely identifying the instrument, but often
+        also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
+        the same ID the Spice expects in bods2c calls.
+
+        Returns
+        -------
+        : str
+          instrument id
+        """
         return self.id_lookup[self.label['IsisCube']['Instrument']['InstrumentId']]
 
     @property
     def focal_plane_tempature(self):
+        """
+        Acquires focal plane tempature from a PDS3 label. Used exclusively in
+        computing focal length.
+
+        Returns
+        -------
+        : double
+          focal plane tempature
+        """
         return self.label['IsisCube']['Instrument']['FocalPlaneTemperature'].value
diff --git a/ale/drivers/mro_driver.py b/ale/drivers/mro_driver.py
index 870d3eca1d40398e2de673a972edbb7e78a2ade0..2cf539b564460845b2db631472e99c521975286e 100644
--- a/ale/drivers/mro_driver.py
+++ b/ale/drivers/mro_driver.py
@@ -11,6 +11,9 @@ from ale.drivers import keys
 
 
 class CtxSpice(Spice, LineScanner):
+    """
+    Spice mixins that defines MRO CTX specific snowflake Spice calls.
+    """
     id_lookup = {
             'CONTEXT CAMERA':'MRO_CTX'
     }
@@ -19,6 +22,14 @@ class CtxSpice(Spice, LineScanner):
 
     @property
     def metakernel(self):
+        """
+        Returns latest instrument metakernels
+
+        Returns
+        -------
+        : string
+          Path to latest metakernel file
+        """
         metakernel_dir = config.mro
         mks = sorted(glob(os.path.join(metakernel_dir,'*.tm')))
         if not hasattr(self, '_metakernel'):
@@ -30,12 +41,31 @@ class CtxSpice(Spice, LineScanner):
 
 
 class CtxPds3Driver(PDS3, CtxSpice):
+    """
+    Driver for reading CTX PDS3 labels. Requires a Spice mixin to acquire addtional
+    ephemeris and instrument data located exclusively in spice kernels.
+    """
+
     @property
     def instrument_id(self):
+        """
+        Returns an instrument id for uniquely identifying the instrument, but often
+        also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
+        the same ID the Spice expects in bods2c calls.
+
+        Returns
+        -------
+        : str
+          instrument id
+        """
         return self.id_lookup[self.label['INSTRUMENT_NAME']]
 
     @property
     def spacecraft_name(self):
+        """
+        Spacecraft name used in various Spice calls to acquire
+        ephemeris data.
+        """
         name_lookup = {
             'MARS_RECONNAISSANCE_ORBITER': 'MRO'
         }
@@ -43,4 +73,14 @@ class CtxPds3Driver(PDS3, CtxSpice):
 
     @property
     def instrument_id(self):
+        """
+        Returns an instrument id for unquely identifying the instrument, but often
+        also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
+        the same ID the Spice expects in bods2c calls.
+
+        Returns
+        -------
+        : str
+          instrument id
+        """
         return self.id_lookup[self.label['INSTRUMENT_NAME']]
diff --git a/src/ale.cpp b/src/ale.cpp
index 5427e9203f97a299706cf4f411d53816daeaddb7..5cf73cd190d8562f841b7500e94614449be3e2c0 100644
--- a/src/ale.cpp
+++ b/src/ale.cpp
@@ -355,11 +355,11 @@ namespace ale {
      PyObject *pDict = PyModule_GetDict(pModule);
 
      // Get the add method from the dictionary.
-     PyObject *pFunc = PyDict_GetItemString(pDict, "loads");
+     PyObject *pFunc = PyDict_GetItemString(pDict, "load");
      if(!pFunc) {
        // import errors do not set a PyError flag, need to use a custom
        // error message instead.
-       throw runtime_error("Failed to import ale.loads function from Python."
+       throw runtime_error("Failed to import ale.load function from Python."
                            "This Usually indicates an error in the Ale Python Library."
                            "Check if Installed correctly and the function ale.loads exists.");
      }
diff --git a/tests/ctests/AleTest.cpp b/tests/ctests/AleTest.cpp
index 6131c4e526b74b9331cbb87424338f89160f97a3..c7c5acae62fe36c5aaf6930e1d924d52395fd5b8 100644
--- a/tests/ctests/AleTest.cpp
+++ b/tests/ctests/AleTest.cpp
@@ -302,7 +302,6 @@ TEST(PyInterfaceTest, LoadInvalidLabel) {
   EXPECT_THROW(ale::load(label), invalid_argument);
 }
 
-
 TEST(AngularVelocityInterpTest, ExampleGetRotation) {
   vector<double> times = {0,  1};
   vector<vector<double>> rots({{0,0}, {1,0}, {0,1}, {0,0}});
diff --git a/tests/pytests/test_lro_drivers.py b/tests/pytests/test_lro_drivers.py
index 05234b7d06ab00892a2707a55f1ddd6fd5faa469..56c81a783290db69d1d90f934a5ab1fe5d1afe85 100644
--- a/tests/pytests/test_lro_drivers.py
+++ b/tests/pytests/test_lro_drivers.py
@@ -5,7 +5,7 @@ import pytest
 
 import ale
 from ale.drivers import lro_driver, base
-from ale.drivers.lro_driver import LroPds3Driver
+from ale.drivers.lro_driver import LrocPds3Driver
 from ale import util
 
 # 'Mock' the spice module where it is imported
@@ -15,7 +15,7 @@ simplespice = SimpleSpice()
 base.spice = simplespice
 lro_driver.spice = simplespice
 
-LroPds3Driver.metakernel = get_mockkernels
+LrocPds3Driver.metakernel = get_mockkernels
 
 @pytest.fixture
 def lro_lroclabel():
@@ -112,7 +112,7 @@ def lro_lroclabel():
         """
 
 def test_lro_creation(lro_lroclabel):
-    with LroPds3Driver(lro_lroclabel) as m:
+    with LrocPds3Driver(lro_lroclabel) as m:
         d = m.to_dict()
         assert isinstance(d, dict)
         assert(set(d.keys()) == m.required_keys)