Source code for astroquery.nasa_ads.core

# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Module to search the SAO/NASA Astrophysics Data System

:author: Magnus Persson <magnusp@vilhelm.nu>

"""
import os

from astropy.table import Table
from urllib.parse import quote as urlencode

from ..query import BaseQuery
from ..utils import async_to_sync
from ..utils.class_or_instance import class_or_instance

from .utils import _get_data_from_xml
from . import conf


from xml.dom import minidom

__all__ = ['ADS', 'ADSClass']


[docs]@async_to_sync class ADSClass(BaseQuery): SERVER = conf.server QUERY_SIMPLE_PATH = conf.simple_path TIMEOUT = conf.timeout ADS_FIELDS = conf.adsfields SORT = conf.sort NROWS = conf.nrows NSTART = conf.nstart TOKEN = conf.token QUERY_SIMPLE_URL = SERVER + QUERY_SIMPLE_PATH def __init__(self, *args): """ set some parameters """ super(ADSClass, self).__init__()
[docs] @class_or_instance def query_simple(self, query_string, get_query_payload=False, get_raw_response=False, cache=True): """ Basic query. Uses a string and the ADS generic query. """ request_string = self._args_to_url(query_string) request_fields = self._fields_to_url() request_sort = self._sort_to_url() request_rows = self._rows_to_url(self.NROWS, self.NSTART) request_url = self.QUERY_SIMPLE_URL + request_string + request_fields + request_sort + request_rows # primarily for debug purposes, but also useful if you want to send # someone a URL linking directly to the data if get_query_payload: return request_url response = self._request(method='GET', url=request_url, headers={'Authorization': 'Bearer ' + self._get_token()}, timeout=self.TIMEOUT, cache=cache) response.raise_for_status() if get_raw_response: return response # parse the XML response into AstroPy Table resulttable = self._parse_response(response.json()) return resulttable
def _parse_response(self, response): try: response['response']['docs'][0]['bibcode'] except IndexError: raise RuntimeError('No results returned!') # get the list of hits hitlist = response['response']['docs'] t = Table() # Grab the various fields and put into AstroPy table for field in self.ADS_FIELDS: tmp = _get_data_from_xml(hitlist, field) t[field] = tmp return t def _args_to_url(self, query_string): # convert arguments to a valid requests payload # i.e. a dictionary request_string = 'q=' + urlencode(query_string) return request_string def _fields_to_url(self): request_fields = '&fl=' + ','.join(self.ADS_FIELDS) return request_fields def _sort_to_url(self): request_sort = '&sort=' + urlencode(self.SORT) return request_sort def _rows_to_url(self, nrows=10, nstart=0): request_rows = '&rows=' + str(nrows) + '&start=' + str(nstart) return request_rows def _get_token(self): """ Try to get token from the places Andy Casey's python ADS client expects it, otherwise return an error """ if self.TOKEN is not None: return self.TOKEN self.TOKEN = os.environ.get('ADS_DEV_KEY', None) if self.TOKEN is not None: return self.TOKEN token_file = os.path.expanduser(os.path.join('~', '.ads', 'dev_key')) try: with open(token_file) as f: self.TOKEN = f.read().strip() return self.TOKEN except IOError: raise RuntimeError('No API token found! Get yours from: ' 'https://ui.adsabs.harvard.edu/#user/settings/token ' 'and store it in the API_DEV_KEY environment variable.')
ADS = ADSClass()