blog.humaneguitarist.org
PyEDS 0.3
[Sun, 13 Oct 2013 21:31:41 +0000]
Doh. I just posted [http://blog.humaneguitarist.org/2013/10/13/order-pyeds-within-the-next-10-minutes-and-receive-php_eds-for-free/] 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.
#PyEDS.py
'''
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; nitaro74@gmail.com
____________________________________________________________________________________________________
#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="config.py")
#sample "config.py" 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 "config.py" 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: http://edswiki.ebscohost.com/API_Reference_Guide:_Appendix
- 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='https://eds-api.ebscohost.com/authservice/rest/UIDAuth',
data=auth_json,
headers={'Content-Type':'application/json',
'Accept':'application/json'})
req_open = urllib2.urlopen(req)
req_results = req_open.read()
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='http://eds-api.ebscohost.com/edsapi/rest/CreateSession',
data=sessionOpen_json,
headers={'Content-Type':'application/json',
'Accept':'application/json',
'x-authenticationToken':__EDS['AuthToken']})
req_open = urllib2.urlopen(req)
req_results = req_open.read()
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='http://eds-api.ebscohost.com//edsapi/rest/EndSession',
data=sessionClose_json,
headers={'Content-Type':'application/json',
'Accept':'application/json',
'x-authenticationToken':__EDS['AuthToken']})
urllib2.urlopen(req)
return
def authenticateFile(config_file='config.py'):
'''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='http://eds-api.ebscohost.com/edsapi/rest/Search?' + 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 = req_open.read()
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='http://eds-api.ebscohost.com/edsapi/rest/Search',
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 = req_open.read()
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='http://eds-api.ebscohost.com/edsapi/rest/Retrieve',
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 = req_open.read()
return req_results
def showInfo():
'''Returns EDS limiters, sort options, search tags, expanders, and search modes available to the profile.'''
req = urllib2.Request(url='http://eds-api.ebscohost.com/edsapi/rest/Info',
headers={'Content-Type':'application/json',
'x-authenticationToken':__EDS['AuthToken'],
'x-sessionToken':__EDS['SessionToken']})
req_open = urllib2.urlopen(req)
req_results = req_open.read()
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.