PyEDS 0.3

[Sun, 13 Oct 2013 21:31:41 +0000]
Doh. I just posted [] a PHP implementation of this and forgot I had updated the Python version. This is small, light code, but it appears to be getting away from me in terms of versioning. Might be time to formalize it as a project. ''' This module provides a basic Python binding to Ebsco's EDS API, allowing one to: - authenticate with a UserID and Password, - open and close a session, - perform a search, - access the EDS Info and Retrieve methods, - pretty print the JSON response. Thanks, Nitin Arora; ____________________________________________________________________________________________________ #Usage example: import PyEDS as eds eds.authenticateUser('USERID_GOES_HERE', 'PASSWORD_GOES_HERE') eds.openSession('PROFILE_GOES_HERE', 'GUEST_GOES_HERE', 'ORG_GOES_HERE') #eds.authenticateFile() #alternative to using authenticateUser() and openSession() #uses values in JSON config file argument(default="") #sample "" file: """ { "EDS_config": { "UserId": "USERID_GOES_HERE", "Password": "PASSWORD_GOES_HERE", "Profile": "PROFILE_GOES_HERE", "Guest": "GUEST_GOES_HERE", "Org": "ORG_GOES_HERE" } } """ kittens = eds.advancedSearch('{"SearchCriteria":{"Queries":[{"Term":"kittens"}],"SearchMode":"smart","IncludeFacets":"y","Sort":"relevance"},"RetrievalCriteria":{"View":"brief","ResultsPerPage":10,"PageNumber":1,"Highlight":"y"},"Actions":null}') puppies = eds.advancedSearch('{"SearchCriteria":{"Queries":[{"Term":"puppies"}],"SearchMode":"smart","IncludeFacets":"y","Sort":"relevance"},"RetrievalCriteria":{"View":"brief","ResultsPerPage":10,"PageNumber":1,"Highlight":"y"},"Actions":null}') cubs = eds.basicSearch('cubs') piglets = eds.basicSearch('piglets', view='brief', offset=1, limit=10, order='relevance') eds.closeSession() ____________________________________________________________________________________________________ CHANGELOG: - version 0.3: - added rawSearch() to support searching with full GET/URL string. - added "Accept':'application/json'" to headers where appropriate. - this doesn't seem necessary but rather proper (the PHP version of this library requires it). - version 0.2: - downgraded version 1.1 to 0.1 ... I was getting ahead of myself! - changed default file in authenticateFile() to "" for security. - changed data structures for everything except basicSearch() and advancedSearch() to be a Python dictionary instead of a JSON string literal. - fixed bug for "HighlightTerms" in retrieveRecord() as it needs to be an array, not a string. - changed global list name to "__EDS" so as to use the Python convention for private names. - made sure all functions end in a return statement. - version 0.1: - added retrieveRecord() and showInfo() methods. - version 0.0: - first version ... that worked! :-] TO DO: - add more options to basicSearch() like "facets", "search mode", "fulltext", "thesauras", etc. - can't hurt! :-] - consider adding an authenticateIP() function that uses the IP authentication method. - deal with expired tokens, etc.; see: - deal with any encoding issues re: Asian language characters returned from showInfo(). - add some error handling stuff. - add examples for new functions up top. ''' import json, urllib2 __EDS = {} def authenticateUser(UserId, Password): '''Authenticates user with an EDS UserId and Password.''' auth_dict = {'UserId':UserId, 'Password':Password, 'InterfaceId':'WSapi'} auth_json = json.dumps(auth_dict) req = urllib2.Request(url='', data=auth_json, headers={'Content-Type':'application/json', 'Accept':'application/json'}) req_open = urllib2.urlopen(req) req_results = req_results_dictionary = eval(req_results) #convert JSON to dictionary. __EDS['AuthToken'] = req_results_dictionary['AuthToken'] __EDS['AuthTimeout'] = req_results_dictionary['AuthTimeout'] return def openSession(Profile, Guest, Org): '''Opens the EDS session with an EDS Profile, the Guest value ("y" or "n"), and the Org nickname.''' sessionOpen_dict = {'Profile':Profile, 'Guest':Guest, 'Org':Org} sessionOpen_json = json.dumps(sessionOpen_dict) req = urllib2.Request(url='', data=sessionOpen_json, headers={'Content-Type':'application/json', 'Accept':'application/json', 'x-authenticationToken':__EDS['AuthToken']}) req_open = urllib2.urlopen(req) req_results = req_results_dictionary = eval(req_results) __EDS['SessionToken'] = req_results_dictionary['SessionToken'].replace('\\/', '/') return def closeSession(): '''Closes the EDS sesssion.''' sessionClose_dict = {'SessionToken':__EDS['SessionToken']} sessionClose_dict = json.dumps(sessionClose_dict) req = urllib2.Request(url='', data=sessionClose_json, headers={'Content-Type':'application/json', 'Accept':'application/json', 'x-authenticationToken':__EDS['AuthToken']}) urllib2.urlopen(req) return def authenticateFile(config_file=''): '''Uses values in config file to authenticate *and* open a session.''' config = open(config_file, 'r').read() config = eval(config) config = config['EDS_config'] authenticateUser(config['UserId'], config['Password']) openSession(config['Profile'], config['Guest'], config['Org']) return def rawSearch(query_string): '''Returns search results using an ampersand-separated URL parameter string.''' req = urllib2.Request(url='' + query_string, headers={'Content-Type':'application/json', 'Accept':'application/json', 'x-authenticationToken':__EDS['AuthToken'], 'x-sessionToken':__EDS['SessionToken']}) req_open = urllib2.urlopen(req) req_results = return req_results def basicSearch(query, view='brief', offset=1, limit=10, order='relevance'): '''Returns search results using basic arguments.''' search_json = '''{"SearchCriteria":{"Queries":[{"Term":"%s"}],"SearchMode":"smart","IncludeFacets":"n","Sort":"%s"}, "RetrievalCriteria":{"View":"%s","ResultsPerPage":%d,"PageNumber":%d,"Highlight":"n"},"Actions":null}''' %(query, order, view, limit, offset) return advancedSearch(search_json) def advancedSearch(search_json): '''Returns search results using the full EDS search syntax (JSON).''' req = urllib2.Request(url='', data=search_json, headers={'Content-Type':'application/json', 'Accept':'application/json', 'x-authenticationToken':__EDS['AuthToken'], 'x-sessionToken':__EDS['SessionToken']}) req_open = urllib2.urlopen(req) req_results = return req_results def retrieveRecord(accession_number, db_code, terms_to_highlight=None, preferred_format='ebook-epub'): '''Returns metadata (including abstract and full-text if applicable) for a single record.''' retrieve_dict = {'EbookPreferredFormat':preferred_format, 'HighlightTerms':terms_to_highlight, 'An':accession_number, 'DbId':db_code} retrieve_json = json.dumps(retrieve_dict) req = urllib2.Request(url='', data=retrieve_json, headers={'Content-Type':'application/json', 'Accept':'application/json', 'x-authenticationToken':__EDS['AuthToken'], 'x-sessionToken':__EDS['SessionToken']}) req_open = urllib2.urlopen(req) req_results = return req_results def showInfo(): '''Returns EDS limiters, sort options, search tags, expanders, and search modes available to the profile.''' req = urllib2.Request(url='', headers={'Content-Type':'application/json', 'x-authenticationToken':__EDS['AuthToken'], 'x-sessionToken':__EDS['SessionToken']}) req_open = urllib2.urlopen(req) req_results = return req_results def prettyPrint(json_string): '''Returns a pretty-printed, UTF-8 encoded JSON string with escaped non-ASCII characters.''' dictionary = json.loads(json_string, encoding='utf=8') return json.dumps(dictionary, ensure_ascii=True, indent=2, encoding='utf-8') #fin ... Update: July, 2015: I've been meaning for the longest time to add that I shouldn't have used "eval()" to load a JSON string as dictionary as I did in the script. I should have used "json.loads()". That's all! Thanks.