Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates according to the newer version of the ORCID APIs #6

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
*.pyc
*.txt
*.log
*.bib
*.tex
17 changes: 17 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
### About

'Ready to run' examples showing how to use **orcid** python module.

### How to run examples
* To run the examples no installation of **orcid** module is required.
* Download latest package from [github](https://github.com/scholrly/orcid-python) and unzip it
* Install dependencies (see file 'requirements.txt')
* Navigate to the subfolder 'examples'
* For instance, to run **extracting_bibtex.py** use following command:
```
python extracting_bibtex.py
```

### Examples
* **extracting_bibtex.py**
- script that extract all BIBTEX files of given author
119 changes: 119 additions & 0 deletions examples/extracting_bibtex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# coding: utf-8

# importing module located in parent folder
import sys
sys.path.insert(0, '../')

# maing testing library
import orcid

# additional libraries
import json
import codecs

# setting logging to the DEBUG mode
import logging

#logging.getLogger("#orcid#").setLevel(logging.DEBUG)
logging.getLogger("#orcid#").setLevel(logging.INFO)

#retrieve my own's profile from his ORCID
me = orcid.get('0000-0001-5661-4587')

def show_keyword(obj):
print obj.keywords
for key_word in obj.keywords:
print key_word

def print_publications(obj):
"""
Printing keywords
"""
print '[i] printing the keywords set by author'
for value in obj.publications:
print value

def save_bibtex(bibtex, file_name='orcid-bibtex-output.bib', encoding='utf-8'):
"""
(dict, str, str) -> None

Saving bibtex to the file, grouped by year.
"""

_file = codecs.open(file_name, 'w', encoding)

for key in bibtex:
_file.write("%%%%%%%%%%%%%%%% \n%% %s \n%%%%%%%%%%%%%%%%\n\n" % key)
bibtex_group = ''
for value in bibtex[key]:
bibtex_group += value + '\n\n'
_file.write(bibtex_group)

_file.close()

print '[i] bibtex was created, check following file: %s ' % (file_name)

def save_nocite(bibtex, file_name='orcid-nocite-output.tex', encoding='utf-8'):
"""
(dict, str, str) -> None

Saving bibtex to the file, grouped by year.
"""

def extract_bibtex_id(s):
start = s.find('{') + 1
end = s.find(',', start)
return s[start:end]

_file = codecs.open(file_name, 'w', encoding)

for key in bibtex:
_file.write("%%%%%%%%%%%%%%%% \n%% %s \n%%%%%%%%%%%%%%%%\n\n" % key)
nocite_group = ''
for value in bibtex[key]:
nocite_group += '\\nocite{' + extract_bibtex_id(value) + '}' + '\n'
_file.write(nocite_group)

_file.close()

print '[i] tex with \\nocite was created, check following file: %s ' % (file_name)

def extract_bitex(obj):
"""
(Class) -> dict()

Method takes as an input object with all publications from ORCID and forms dict with it.
"""

bibtex = {}
for value in obj.publications:
if value.citation.citation_type == 'BIBTEX':
if value.publicationyear not in bibtex:
bibtex[value.publicationyear] = list()
bibtex[value.publicationyear].append(value.citation.citation)
else:
bibtex[value.publicationyear].append(value.citation.citation)
else:
print '[i] this publications is having no BIBTEX %s ' % (value)

return bibtex

def orcid_bibtex(obj):
"""
(Class) -> None

Extrating bibtex from ORCID, saving it to the file
"""

# extracting bibtex
orcid_bibtex = extract_bitex(me)

# saving bibtex to file
save_bibtex(orcid_bibtex)

# citing extracted bibtex
save_nocite(orcid_bibtex)

#show_keyword(me)
#print_publications(me)
orcid_bibtex(me)
32 changes: 29 additions & 3 deletions orcid/rest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import requests
import json

from .constants import ORCID_PUBLIC_BASE_URL
from .utils import dictmapper, MappingRule as to

from .exceptions import NotFoundException

# setting logger
import logging
logger = logging.getLogger("#orcid#")
logging.basicConfig(filename='orcid-log.log', level=logging.INFO)


BASE_HEADERS = {'Accept':'application/orcid+json'}

BIO_PATH = ['orcid-profile','orcid-bio']
Expand All @@ -15,7 +22,8 @@ def _parse_keywords(d):
# (https://github.com/ORCID/ORCID-Parent/issues/27) makes this the best
# way. will fix when they do
if d is not None:
return d.get('keyword',[{}])[0].get('value','').split(',')
#return d.get('keyword',[{}])[0].get('value','').split(',')
return [val['value'] for val in d['keyword']]
return []

WebsiteBase = dictmapper('WebsiteBase', {
Expand Down Expand Up @@ -63,9 +71,10 @@ def __repr__(self):
'title':['work-title','title','value'],
'subtitle':['work-title','subtitle','value'],
'url':['url','value'],
'citation':to(['citation'], lambda d: Citation(d) if d is not None else None),
'citation': to(['work-citation'], lambda d: Citation(d) if d is not None else None),
'external_ids':to(['work-external-identifiers','work-external-identifier'],
lambda l: map(ExternalID, l) if l is not None else None),
'publicationyear': ['publication-date', 'year', 'value'],
})

class Publication(PublicationBase):
Expand All @@ -76,6 +85,7 @@ def __repr__(self):

def _parse_publications(l):
if l is not None:
#logger.debug(json.dumps(l, sort_keys=True, indent=4, separators=(',', ': ')))
return [Publication(d) for d in l]
return []

Expand All @@ -84,11 +94,12 @@ def _parse_publications(l):
})

AuthorBase = dictmapper('AuthorBase', {
'orcid':['orcid-profile','orcid','value'],
'orcid':['orcid-profile','orcid-identifier','path'],
'family_name':PERSONAL_DETAILS_PATH + ['family-name','value'],
'given_name':PERSONAL_DETAILS_PATH + ['given-names','value'],
'biography':BIO_PATH + ['biography',],
'keywords':to(BIO_PATH + ['keywords'], _parse_keywords),
#'keywords':to(BIO_PATH + ['keywords', 'keyword'], _parse_keywords),
'researcher_urls':to(BIO_PATH + ['researcher-urls','researcher-url'],
_parse_researcher_urls),
})
Expand All @@ -99,6 +110,7 @@ class Author(AuthorBase):
def _load_works(self):
resp = requests.get(ORCID_PUBLIC_BASE_URL + self.orcid
+ '/orcid-works', headers = BASE_HEADERS)
logger.debug(json.dumps(resp.json(), sort_keys=True, indent=4, separators=(',', ': ')))
self._loaded_works = Works(resp.json())

@property
Expand All @@ -116,15 +128,29 @@ def __repr__(self):
'citation_type':['work-citation-type']
})

def write_logs(resp):
logger.debug(json.dumps(resp.json(), sort_keys=True, indent=4, separators=(',', ': ')))

def get(orcid_id):
"""
Get an author based on an ORCID identifier.
"""
resp = requests.get(ORCID_PUBLIC_BASE_URL + unicode(orcid_id),
headers=BASE_HEADERS)
write_logs(resp)
json_body = resp.json()
return Author(json_body)

# def get_with_json(orcid_id):
# """
# Get an author based on an ORCID identifier and json
# """
# resp = requests.get(ORCID_PUBLIC_BASE_URL + unicode(orcid_id),
# headers=BASE_HEADERS)
# json_body = resp.json()
# write_logs(resp)
# return Author(json_body), json_body

def search(query):
resp = requests.get(ORCID_PUBLIC_BASE_URL + 'search/orcid-bio',
params={'q':unicode(query)}, headers=BASE_HEADERS)
Expand Down