Index: /branches/sc_branches/psps_testing/psi/psi_inquisitor.py
===================================================================
--- /branches/sc_branches/psps_testing/psi/psi_inquisitor.py	(revision 29115)
+++ /branches/sc_branches/psps_testing/psi/psi_inquisitor.py	(revision 29115)
@@ -0,0 +1,93 @@
+from suds.client import Client
+from suds.xsd.doctor import Import, ImportDoctor
+from suds import sudsobject
+
+class PsiInquisitor:
+    def __init__(self, configuration_file):
+        """
+        >>> psiInquisitor = PsiInquisitor('psi.web01_configuration')
+        >>> print psiInquisitor.configuration.userID
+        schastel
+        >>> print psiInquisitor.configuration.password
+        d1str1ct13
+        >>> print psiInquisitor.configuration.schemaGroup
+        PS1_SCHEMA
+        >>> print psiInquisitor.configuration.context
+        PS1 3PI
+        """
+        # If you're unfamiliar with dynamic module importation, look at:
+        # http://docs.python.org/library/functions.html#__import__ and 
+        # http://www.diveintopython.org/functional_programming/dynamic_import.html
+        # Importation could also be done this way (2 next lines):
+        # exec 'from %s import Configuration' % configuration_file
+        # self.configuration = Configuration
+        self.configuration = __import__(configuration_file, globals(), locals(), 
+                                        ['Configuration'], -1).Configuration
+        self.authClient = Client(self.configuration.authUrl)
+        self.sessionID = self.authClient.service.login(self.configuration.userID, 
+                                                       self.configuration.password)
+        # Found that as a usual trick when problems occur. See
+        # http://stackoverflow.com/questions/1329190/python-suds-type-not-found-xscomplextype
+        imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
+        doctor = ImportDoctor(imp)
+        self.jobsClient = Client(self.configuration.jobsUrl, doctor=doctor)
+
+    def query(self, sql_query):
+        """
+        Make a query in the fast queue.
+        
+        >>> query = 'select frameID from FrameMeta where frameID=105439;'
+        >>> psiInquisitor = PsiInquisitor('psi.web01_configuration')
+        >>> result = psiInquisitor.query(query)
+        >>> # we cannot guarantee the order in result
+        >>> print result['items']
+        [{u'[frameID]': u'105439'}]
+        >>> print result['fields']
+        [u'[frameID]']
+        >>> print result['types']
+        {u'[frameID]': u'Integer'}
+        >>> # This test has to be completed with exhaustive ones...
+        >>> # e.g. unit tests against the csr data base.
+        """
+        results = self.jobsClient.service.executeQuickJob(self.sessionID, 
+                                                          self.configuration.schemaGroup,
+                                                          sql_query, 
+                                                          self.configuration.context)
+        lines = results.split('\n')
+        first_line_not_seen = True
+        fields = []
+        types_dictionary = {}
+        contents = {}
+        contents['items'] = []
+        line_count = 0
+        for line in lines:
+            if first_line_not_seen:
+                # Build up the field list and the types dictionary
+                # from the type list csv They are in the first line
+                # and shown like: [field_key]:type
+                for element in line.split(','):
+                    dummy = element.split(':')
+                    fields.append(dummy[0])
+                    types_dictionary[dummy[0]] = dummy[1]
+                contents['fields'] = fields
+                contents['types'] = types_dictionary
+                first_line_not_seen = False
+            else:
+                # Other lines contain data. We index them using their
+                # position...
+                values = line.split(',')
+                if len(values) != len(contents['fields']):
+                    # I wonder if this test is relevant.
+                    # We should trust the server response at least
+                    # at the protocol level...
+                    raise Exception("Different array length? %d vs %d" 
+                                    % (len(values), len(contents['fields'])))
+                element = {}
+                for i in range(len(values)):
+                    element[contents['fields'][i]] = values[i]
+                contents['items'].append(element)
+        return contents
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
Index: /branches/sc_branches/psps_testing/psi/web01_configuration.py
===================================================================
--- /branches/sc_branches/psps_testing/psi/web01_configuration.py	(revision 29115)
+++ /branches/sc_branches/psps_testing/psi/web01_configuration.py	(revision 29115)
@@ -0,0 +1,11 @@
+class Configuration:
+    """
+    The configuration described as a class...
+    """
+    server = 'http://web01.psps.ifa.hawaii.edu/'
+    authUrl = server + 'DFetch/WSDL/AuthService.php.wsdl'
+    userID = 'schastel'
+    password = 'd1str1ct13'
+    schemaGroup = 'PS1_SCHEMA';
+    context     = 'PS1 3PI';
+    jobsUrl = server + 'DFetch/WSDL/JobsService.php.wsdl'
