<commit_before># Licensed under a 3-clause BSD style license - see LICENSE.rst
import types
import functools
import requests
from astropy.table import Table, Column
import astropy.units as u
import astropy.utils.data as aud
import astropy.coordinates as coord
from astropy.io import fits
from . import utils
from . import IRSA_DUST_SERVER, IRSA_DUST_TIMEOUT
from ..utils.class_or_instance import class_or_instance
from ..exceptions import TimeoutError, InvalidQueryError
from ..query import BaseQuery

# TODO Add support for server url from JSON cache
__all__ = ["IrsaDust"]

EXT_DESC = "E(B-V) Reddening"
EM_DESC = "100 Micron Emission"
TEMP_DESC = "Dust Temperature"

INPUT = "input"
OBJ_NAME = "objname"
REG_SIZE = "regSize"
DESC = "desc"
IMAGE_URL = "imageUrl"

STATISTICS = "statistics"
REF_PIXEL_VALUE = "refPixelValue"
REF_COORDINATE = "refCoordinate"
MEAN_VALUE = "meanValue"
STD = "std"
MAX_VALUE = "maxValue"
MIN_VALUE = "minValue"

DATA_IMAGE = "./data/image"
DATA_TABLE = "./data/table"

# make generic enough to move to BaseQuery classf_ar


def send_request(url, data, timeout):
    """
    A utility function that post HTTP requests to remote server
    and returns the HTTP response.

    Parameters
    ----------
    url : str
        The URL of the remote server
    data : dict
        A dictionary representing the payload to be posted via the HTTP request
    timeout : int
        Time limit for establishing successful connection with remote server

    Returns
    -------
    response : `requests.Response`
        Response object returned by the remote server
    """
    try:
        response = requests.post(url, data=data, timeout=timeout)
        return response
    except requests.exceptions.Timeout:
            raise TimeoutError("Query timed out, time elapsed {time}s".
                               format(time=timeout))
    except requests.exceptions.RequestException:
            raise Exception("Query failed\n")


class IrsaDust(BaseQuery):

    DUST_SERVICE_URL = IRSA_DUST_SERVER()
    TIMEOUT = IRSA_DUST_TIMEOUT()
    image_type_to_section = {
        'extinction': 't',
        'ebv': 'r',
        '100um': 'e'
    }

    def __init__(self, *args):
        pass

    @class_or_instance
    def get_images(self, coordinate, radius=None,
                   image_type=None, timeout=TIMEOUT, get_query_payload=False):
        """
        A query function that performs a coordinate-based query to acquire Irsa-Dust images

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html.
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        image_type : str, optional
            When missing returns for all the images. Otherwise returns only
            for image of the specified type which must be one of `extinction`, `ebv`,
            `100um`. Defaults to `None`.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`.
        get_query_payload : bool, optional
            If true than returns the dictionary of query parameters, posted to
            remote server. Defaults to `False`.

        Returns
        -------
        A list of `astropy.fits.HDUList` objects

        Examples
        ---------
        Query an object by name with default radius and get a list of
        astropy.fits.HDUList objects.
        >>> fits_objects = IrsaDust.get_images('m81')

        Query an object specifying the coordinates and the radius
        >>> fits_objects = IrsaDust.get_images('266.12 -61.89 equ j2000', radius=5 * u.deg)

        Only return the dictionary formed from the query parameters
        >>> query_payload = get_images('34.5565 54.2321 gal', radius='0.13 rad')
        """

        if get_query_payload:
            return self._args_to_payload(coordinate, radius=radius)
        readable_objs = self.get_images_async(
            coordinate, radius=radius, image_type=image_type,
            timeout=timeout, get_query_payload=get_query_payload)
        return [fits.open(obj.__enter__()) for obj in readable_objs]

    @class_or_instance
    def get_images_async(self, coordinate, radius=None,
                         image_type=None, timeout=TIMEOUT, get_query_payload=False):
        """
        A query function similar to `astroquery.irsa_dust.IrsaDust.get_images` but
        returns file-handlers to the remote files rather than downloading them. Useful
        for asynchronous queries so that the actual download may be performed later.

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        image_type : str, optional
            When missing returns for all the images. Otherwise returns only
            for image of the specified type which must be one of `extinction`, `ebv`,
            `100um`. Defaults to `None`.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`
        get_query_payload : bool, optional
            If true than returns the dictionary of query parameters, posted to
            remote server. Defaults to `False`

        Returns
        --------
        A list of context-managers that yield readable file-like objects
        """

        if get_query_payload:
            return self._args_to_payload(coordinate, radius=radius)
        image_urls = self.get_image_list(coordinate, radius=radius,
                                         image_type=image_type, timeout=timeout)
        return [aud.get_readable_fileobj(U) for U in image_urls]

    @class_or_instance
    def get_image_list(
            self, coordinate, radius=None, image_type=None, timeout=TIMEOUT):
        """
        Query function that performes coordinate-based query and returns a list of
        URLs to the Irsa-Dust images

        Parameters
        -----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        image_type : str, optional
            When missing returns for all the images. Otherwise returns only
            for image of the specified type which must be one of `extinction`,
            `ebv`, `100um`. Defaults to `None`.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`
        get_query_payload : bool
            If true than returns the dictionary of query parameters, posted to
            remote server. Defaults to `False`

        Returns
        --------
        A list of URLs to the FITS images corresponding to the queried object
        """
        url = IrsaDust.DUST_SERVICE_URL
        request_payload = self._args_to_payload(coordinate, radius=radius)
        response = send_request(url, request_payload, timeout)
        return self.extract_image_urls(response.text, image_type=image_type)

    @class_or_instance
    def get_extinction_table(self, coordinate, radius=None, timeout=TIMEOUT):
        """
        Query function that fetches the extinction table from the query
        result

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`

        Returns
        --------
        table : `astropy.table.Table`
        """
        readable_obj = self.get_extinction_table_async(
            coordinate, radius=radius, timeout=timeout)
        table = Table.read(readable_obj.__enter__(), format='ipac')
        return table

    @class_or_instance
    def get_extinction_table_async(
            self, coordinate, radius=None, timeout=TIMEOUT):
        """
        A query function similar to `astroquery.irsa_dust.IrsaDust.get_extinction_table`
        but returns a file-handler to the remote files rather than downloading it.
        Useful for asynchronous queries so that the actual download may be performed later.

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle. Defaults
            to 5 degrees.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`

        Returns
        -------
        A context manager that yields a file like readable object
        """
        url = IrsaDust.DUST_SERVICE_URL
        request_payload = self._args_to_payload(coordinate, radius=radius)
        response = send_request(url, request_payload, timeout)
        xml_tree = utils.xml(response.text)
        result = SingleDustResult(xml_tree, coordinate)
        return aud.get_readable_fileobj(result.ext_detail_table())

    @class_or_instance
    def get_query_table(self, coordinate, radius=None,
                        section=None, timeout=TIMEOUT, url=DUST_SERVICE_URL):
        """
        Create and return an astropy Table representing the query response(s).
        When `section` is missing, returns the full table. When a
        section is specified (`location`, `extinction`, `ebv`, or `100um`),
        only that portion of the table is returned.

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        section : str, optional
            When missing, all the sections of the query result are returned.
            Otherwise only the specified section (`ebv`, `100um`, extinction`,
            `location`) is returned. Defaults to `None`
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`
        url : str, optional
            Only provided for debugging. Should generally not be assigned.
            Defaults to `astroquery.irsa_dust.IrsaDust.DUST_SERVICE_URL

        Returns
        --------
        table : `astropy.table.Table`
            table representing the query results, (all or as per  specified)
        """
        request_payload = self._args_to_payload(coordinate, radius=radius)
        response = send_request(url, request_payload, timeout)
        xml_tree = utils.xml(response.text)
        result = SingleDustResult(xml_tree, coordinate)
        if section is None or section in ["location", "loc", "l"]:
            return result.table(section=section)
        try:
            section = IrsaDust.image_type_to_section[section]
            return result.table(section=section)
        except KeyError:
            msg = ('section must be one of the following:\n'
                   'ebv, extinction, location or 100um.')
            raise ValueError(msg)

    @class_or_instance
    def _args_to_payload(self, coordinate, radius=None):
        """
        Accepts the query parameters and returns a dictionary
        suitable to be sent as data via a HTTP POST request

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.

        Returns
        -------
        payload : dict
            A dictionary that specifies the data for an HTTP POST request
        """
        payload = {"locstr": coordinate}  # check if this is resolvable?
        # check if radius is given with proper units
        if radius is not None:
            try:
                if isinstance(radius, basestring):
                    reg_size = self._parse_as_angle(radius)
                else:
                    reg_size = self._parse_as_quantity(radius)
            # astropy v0.2.x throws UnitsError and v>0.2.x throws
            # UnitsException
            except (u.UnitsException, coord.errors.UnitsError) as ex:
                raise Exception("Radius not specified with proper unit.")
            # check if radius falls in the acceptable range
            if reg_size < 2 or reg_size > 37.5:
                raise ValueError("Radius (in any unit) must be in the"
                                 " range of 2.0 to 37.5 degrees")
            payload["regSize"] = reg_size
        return payload

    @class_or_instance
    def _parse_as_angle(self, radius):
        """
        Helper function for _args_to_payload, parses the
        given string as an `astropy.coordinates.Angle` and
        returns its value in degrees

        Parameters
        ----------
        radius : str
            string representing the angle

        Returns
        -------
        int
            value of angle in degrees
        """
        return coord.Angle(radius).degrees

    @class_or_instance<commit_msg>Added AttributeError while parsing quantities<commit_after># Licensed under a 3-clause BSD style license - see LICENSE.rst
import types
import functools
import requests
from astropy.table import Table, Column
import astropy.units as u
import astropy.utils.data as aud
import astropy.coordinates as coord
from astropy.io import fits
from . import utils
from . import IRSA_DUST_SERVER, IRSA_DUST_TIMEOUT
from ..utils.class_or_instance import class_or_instance
from ..exceptions import TimeoutError, InvalidQueryError
from ..query import BaseQuery

# TODO Add support for server url from JSON cache
__all__ = ["IrsaDust"]

EXT_DESC = "E(B-V) Reddening"
EM_DESC = "100 Micron Emission"
TEMP_DESC = "Dust Temperature"

INPUT = "input"
OBJ_NAME = "objname"
REG_SIZE = "regSize"
DESC = "desc"
IMAGE_URL = "imageUrl"

STATISTICS = "statistics"
REF_PIXEL_VALUE = "refPixelValue"
REF_COORDINATE = "refCoordinate"
MEAN_VALUE = "meanValue"
STD = "std"
MAX_VALUE = "maxValue"
MIN_VALUE = "minValue"

DATA_IMAGE = "./data/image"
DATA_TABLE = "./data/table"

# make generic enough to move to BaseQuery classf_ar


def send_request(url, data, timeout):
    """
    A utility function that post HTTP requests to remote server
    and returns the HTTP response.

    Parameters
    ----------
    url : str
        The URL of the remote server
    data : dict
        A dictionary representing the payload to be posted via the HTTP request
    timeout : int
        Time limit for establishing successful connection with remote server

    Returns
    -------
    response : `requests.Response`
        Response object returned by the remote server
    """
    try:
        response = requests.post(url, data=data, timeout=timeout)
        return response
    except requests.exceptions.Timeout:
            raise TimeoutError("Query timed out, time elapsed {time}s".
                               format(time=timeout))
    except requests.exceptions.RequestException:
            raise Exception("Query failed\n")


class IrsaDust(BaseQuery):

    DUST_SERVICE_URL = IRSA_DUST_SERVER()
    TIMEOUT = IRSA_DUST_TIMEOUT()
    image_type_to_section = {
        'extinction': 't',
        'ebv': 'r',
        '100um': 'e'
    }

    def __init__(self, *args):
        pass

    @class_or_instance
    def get_images(self, coordinate, radius=None,
                   image_type=None, timeout=TIMEOUT, get_query_payload=False):
        """
        A query function that performs a coordinate-based query to acquire Irsa-Dust images

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html.
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        image_type : str, optional
            When missing returns for all the images. Otherwise returns only
            for image of the specified type which must be one of `extinction`, `ebv`,
            `100um`. Defaults to `None`.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`.
        get_query_payload : bool, optional
            If true than returns the dictionary of query parameters, posted to
            remote server. Defaults to `False`.

        Returns
        -------
        A list of `astropy.fits.HDUList` objects

        Examples
        ---------
        Query an object by name with default radius and get a list of
        astropy.fits.HDUList objects.
        >>> fits_objects = IrsaDust.get_images('m81')

        Query an object specifying the coordinates and the radius
        >>> fits_objects = IrsaDust.get_images('266.12 -61.89 equ j2000', radius=5 * u.deg)

        Only return the dictionary formed from the query parameters
        >>> query_payload = get_images('34.5565 54.2321 gal', radius='0.13 rad')
        """

        if get_query_payload:
            return self._args_to_payload(coordinate, radius=radius)
        readable_objs = self.get_images_async(
            coordinate, radius=radius, image_type=image_type,
            timeout=timeout, get_query_payload=get_query_payload)
        return [fits.open(obj.__enter__()) for obj in readable_objs]

    @class_or_instance
    def get_images_async(self, coordinate, radius=None,
                         image_type=None, timeout=TIMEOUT, get_query_payload=False):
        """
        A query function similar to `astroquery.irsa_dust.IrsaDust.get_images` but
        returns file-handlers to the remote files rather than downloading them. Useful
        for asynchronous queries so that the actual download may be performed later.

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        image_type : str, optional
            When missing returns for all the images. Otherwise returns only
            for image of the specified type which must be one of `extinction`, `ebv`,
            `100um`. Defaults to `None`.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`
        get_query_payload : bool, optional
            If true than returns the dictionary of query parameters, posted to
            remote server. Defaults to `False`

        Returns
        --------
        A list of context-managers that yield readable file-like objects
        """

        if get_query_payload:
            return self._args_to_payload(coordinate, radius=radius)
        image_urls = self.get_image_list(coordinate, radius=radius,
                                         image_type=image_type, timeout=timeout)
        return [aud.get_readable_fileobj(U) for U in image_urls]

    @class_or_instance
    def get_image_list(
            self, coordinate, radius=None, image_type=None, timeout=TIMEOUT):
        """
        Query function that performes coordinate-based query and returns a list of
        URLs to the Irsa-Dust images

        Parameters
        -----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        image_type : str, optional
            When missing returns for all the images. Otherwise returns only
            for image of the specified type which must be one of `extinction`,
            `ebv`, `100um`. Defaults to `None`.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`
        get_query_payload : bool
            If true than returns the dictionary of query parameters, posted to
            remote server. Defaults to `False`

        Returns
        --------
        A list of URLs to the FITS images corresponding to the queried object
        """
        url = IrsaDust.DUST_SERVICE_URL
        request_payload = self._args_to_payload(coordinate, radius=radius)
        response = send_request(url, request_payload, timeout)
        return self.extract_image_urls(response.text, image_type=image_type)

    @class_or_instance
    def get_extinction_table(self, coordinate, radius=None, timeout=TIMEOUT):
        """
        Query function that fetches the extinction table from the query
        result

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`

        Returns
        --------
        table : `astropy.table.Table`
        """
        readable_obj = self.get_extinction_table_async(
            coordinate, radius=radius, timeout=timeout)
        table = Table.read(readable_obj.__enter__(), format='ipac')
        return table

    @class_or_instance
    def get_extinction_table_async(
            self, coordinate, radius=None, timeout=TIMEOUT):
        """
        A query function similar to `astroquery.irsa_dust.IrsaDust.get_extinction_table`
        but returns a file-handler to the remote files rather than downloading it.
        Useful for asynchronous queries so that the actual download may be performed later.

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle. Defaults
            to 5 degrees.
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`

        Returns
        -------
        A context manager that yields a file like readable object
        """
        url = IrsaDust.DUST_SERVICE_URL
        request_payload = self._args_to_payload(coordinate, radius=radius)
        response = send_request(url, request_payload, timeout)
        xml_tree = utils.xml(response.text)
        result = SingleDustResult(xml_tree, coordinate)
        return aud.get_readable_fileobj(result.ext_detail_table())

    @class_or_instance
    def get_query_table(self, coordinate, radius=None,
                        section=None, timeout=TIMEOUT, url=DUST_SERVICE_URL):
        """
        Create and return an astropy Table representing the query response(s).
        When `section` is missing, returns the full table. When a
        section is specified (`location`, `extinction`, `ebv`, or `100um`),
        only that portion of the table is returned.

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.
        section : str, optional
            When missing, all the sections of the query result are returned.
            Otherwise only the specified section (`ebv`, `100um`, extinction`,
            `location`) is returned. Defaults to `None`
        timeout : int, optional
            Time limit for establishing successful connection with remote server.
            Defaults to `astroquery.irsa_dust.IrsaDust.TIMEOUT`
        url : str, optional
            Only provided for debugging. Should generally not be assigned.
            Defaults to `astroquery.irsa_dust.IrsaDust.DUST_SERVICE_URL

        Returns
        --------
        table : `astropy.table.Table`
            table representing the query results, (all or as per  specified)
        """
        request_payload = self._args_to_payload(coordinate, radius=radius)
        response = send_request(url, request_payload, timeout)
        xml_tree = utils.xml(response.text)
        result = SingleDustResult(xml_tree, coordinate)
        if section is None or section in ["location", "loc", "l"]:
            return result.table(section=section)
        try:
            section = IrsaDust.image_type_to_section[section]
            return result.table(section=section)
        except KeyError:
            msg = ('section must be one of the following:\n'
                   'ebv, extinction, location or 100um.')
            raise ValueError(msg)

    @class_or_instance
    def _args_to_payload(self, coordinate, radius=None):
        """
        Accepts the query parameters and returns a dictionary
        suitable to be sent as data via a HTTP POST request

        Parameters
        ----------
        coordinate : str
            Can be either the name of an object or a coordinate string
            If a name, must be resolveable by NED, SIMBAD, 2MASS, or SWAS.
            Examples of acceptable coordinate strings, can be found here:
            http://irsa.ipac.caltech.edu/applications/DUST/docs/coordinate.html
        radius : str/astropy.units.Quantity, optional
            The size of the region to include in the dust query, in radian, degree
            or hour as per format specified by `astropy.coordinates.Angle or `astropy
            .units.Quantity`. Defaults to 5 degrees.

        Returns
        -------
        payload : dict
            A dictionary that specifies the data for an HTTP POST request
        """
        payload = {"locstr": coordinate}  # check if this is resolvable?
        # check if radius is given with proper units
        if radius is not None:
            try:
                if isinstance(radius, basestring):
                    reg_size = self._parse_as_angle(radius)
                else:
                    reg_size = self._parse_as_quantity(radius)
            # astropy v0.2.x throws UnitsError and v>0.2.x throws
            # UnitsException
            except (u.UnitsException, coord.errors.UnitsError, AttributeError):
                raise Exception("Radius not specified with proper unit.")
            # check if radius falls in the acceptable range
            if reg_size < 2 or reg_size > 37.5:
                raise ValueError("Radius (in any unit) must be in the"
                                 " range of 2.0 to 37.5 degrees")
            payload["regSize"] = reg_size
        return payload

    @class_or_instance
    def _parse_as_angle(self, radius):
        """
        Helper function for _args_to_payload, parses the
        given string as an `astropy.coordinates.Angle` and
        returns its value in degrees

        Parameters
        ----------
        radius : str
            string representing the angle

        Returns
        -------
        int
            value of angle in degrees
        """
        return coord.Angle(radius).degrees

    @class_or_instance
{'fraction_non_alphanumeric': 0.07302755642070685, 'fraction_numerical': 0.005048968915384148, 'mean_word_length': 2.193996502817175, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5188785', 'n_tokens_mistral': 8613, 'n_tokens_neox': 8331, 'n_words': 3080}