source: ndgCommon/trunk/ndg/common/src/clients/http/vocabserverclient.py @ 5135

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/ndgCommon/trunk/ndg/common/src/clients/http/vocabserverclient.py@5135
Revision 5135, 6.0 KB checked in by cbyrom, 12 years ago (diff)

Add new method for vocab server client to allow vocab terms to be searched.

Line 
1'''
2Simple client to a vocab server - using a POX (plain old XML) interface
3 
4 @author: B Lawrence?, C Byrom, Tessella, Feb 09
5'''
6import logging, urlparse
7from xml.etree import ElementTree as ET
8from generichttpclient import GenericHTTPClient
9from ndg.common.src.models.ndgObject import ndgObject
10from ndg.common.src.lib.utilities import httpify
11from ndg.common.src.models.codetabletype import CodeTableType
12from ndg.common.src.models.codetablerecord import CodeTableRecord
13
14class VocabServerClient(GenericHTTPClient):
15    '''
16    Provides a POX interface to the vocab server
17    '''
18   
19    GET_LIST_QUERY = '%sgetList?recordKey=%s'
20    WHAT_LISTS_QUERY = '%swhatLists'
21    SEARCH_VOCAB_QUERY = '%ssearchVocab?listKey=%s&searchTerm=%s'
22   
23    def __init__(self, 
24                 path = "http://vocab.ndg.nerc.ac.uk/axis2/services/vocab/",
25                 proxyServer = None):
26        logging.debug("Instantiating VocabServerClient")
27        self.path = path
28       
29        # extract the hostname - NB, the parser assumes an http prefix so ensure
30        # this is there
31        url = httpify(path)
32        parsedURL = urlparse.urlparse(url)
33        self.ns = "%s://%s/" %(parsedURL.scheme, parsedURL.hostname)
34
35           
36        super(VocabServerClient, self).__init__(proxyServer = proxyServer)
37        logging.debug("VocabServerClient instantiated")
38
39
40    def getRelated(self,subject):
41        '''
42        Get a related record
43        @param subject: subject text to search for in vocab server
44        @return 2D array of results:
45        [0] - broad result matches
46        [1] - narrow result matches
47        [2] - synonym matches
48        TODO: not sure this actually works since it's difficult to get back
49        any meaningful results.  Possibly things are the wrong way around - the
50        results only return the subject - whereas the interesting info is in a
51        parent entry term to this
52        '''
53        logging.debug("Getting vocab data on subject term, '%s'" %subject)
54        url='%sgetRelatedRecordByCriteria?subjectText=%s&predicate=255&inferences=True&objectList=%slist/P211/current'%(self.path,subject,self.ns)
55        doc = self.readURL(url)
56        x=ET.fromstring(doc)
57        b=x.findall('*/{%s}broadMatch' %ndgObject.VOCAB_NS)
58        n=x.findall('*/{%s}narrowMatch' %ndgObject.VOCAB_NS)
59        s=x.findall('*/{%s}exactMatch' %ndgObject.VOCAB_NS)
60        self.broader=[(i.findtext('{%s}entryTerm' %ndgObject.VOCAB_NS)) for i in b]
61        self.narrower=[(i.findtext('{%s}entryTerm' %ndgObject.VOCAB_NS)) for i in n]
62        self.synonyms=[(i.findtext('{%s}entryTerm' %ndgObject.VOCAB_NS)) for i in s]
63        logging.debug("- returning info on subject term")
64        return [self.broader,self.narrower,self.synonyms]
65
66   
67    def getList(self, listKey):
68        '''
69        Retrieve contents of a list - or a specific term in a list
70        @param listKey: key to use to retrieve list - e.g.
71        for list: http://vocab.ndg.nerc.ac.uk/list/P071/11
72        for term: http://vocab.ndg.nerc.ac.uk/term/P071/11/CFV10N55
73        @raise SystemError if the service returns an error
74        @raise IOError if an invalid listKey is provided
75        @raise SystemError if returned doc features an error
76        @return ElementTree with all data loaded - or None, if nothing retrieved
77        '''
78        logging.debug("Retrieving list info for key, '%s'" %listKey)
79        url = self.GET_LIST_QUERY%(self.path, listKey)
80        doc = self.readURL(url)
81        et = ET.fromstring(doc)
82        error = et.findtext('{%s}error' %ndgObject.VOCAB_NS)
83       
84        # check for errors
85        if error != 'false':
86            raise SystemError("Problem occurred whilst looking up vocab data: %s" %error)
87       
88        logging.debug("- returning info in Elementtree object")
89        return et
90   
91   
92    def getListInfo(self, listKey):
93        '''
94        Retrieve info on a vocab list
95        @param listKey: url of the vocab list
96        @raise SystemError: if vocab lookup fails
97        @raise ValueError: if no list info found
98        @return CodeTableType with data about specified list
99        '''
100        logging.debug("Retrieving info on list with key, '%s'" %listKey)
101        url = self.WHAT_LISTS_QUERY %(self.path)
102        doc = self.readURL(url)
103        et = ET.fromstring(doc)
104
105        error = et.findtext('{%s}error' %ndgObject.VOCAB_NS)
106        if error != 'false':
107            raise SystemError("Problem occurred whilst looking up vocab list: %s" %error)
108
109        recordElements = et.findall('{%s}codeTableType' %ndgObject.VOCAB_NS)
110       
111        for record in recordElements:
112            ctr = CodeTableType(et = record)
113            if ctr.listKey == listKey:
114                logging.debug("- found the specified list - returning data as CodeTableType")
115                return ctr
116           
117        raise ValueError("Vocab list, '%s' not found" %listKey)       
118       
119       
120    def searchVocabTerm(self, vocabListKey, searchTerm):
121        '''
122        Search the specified vocab list for terms matching the input searchTerm
123        @param vocabListKey: url of the vocab list
124        @param searchTerm: term to search on - NB, accepts '*' wildcard for any character
125        @return list of CodeTableRecords matching the search criteria
126        '''
127        logging.debug("Searching for vocab terms matching the input filter, '%s' in vocab list, '%s'" 
128                      %(searchTerm, vocabListKey))
129        url = self.SEARCH_VOCAB_QUERY %(self.path, vocabListKey, searchTerm)
130        doc = self.readURL(url)
131        et = ET.fromstring(doc)
132
133        error = et.findtext('{%s}error' %ndgObject.VOCAB_NS)
134        if error != 'false':
135            raise SystemError("Problem occurred whilst searching vocab data: %s" %error)
136
137        recordElements = et.findall('{%s}codeTableRecord' %ndgObject.VOCAB_NS)
138       
139        self.records = []
140        for record in recordElements:
141            self.records.append(CodeTableRecord(et = record))
142       
143        logging.debug("- returning %s results" %len(self.records))
144        return self.records
Note: See TracBrowser for help on using the repository browser.