<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def query_api(app, client_id, imgur_id, is_album):
 """Query the Imgur API. :raise APIError: When Imgur responds with errors or unexpected data. :param sphinx.application.Sphinx app: Sphinx application object. :param str client_id: Imgur API client ID to use. https://api.imgur.com/oauth2 :param str imgur_id: The Imgur ID to query. :param bool is_album: If this ID is an album instead of an image. :return: Parsed JSON. :rtype: dict """

    url = API_URL.format(type='album' if is_album else 'image', id=imgur_id)
    headers = {'Authorization': 'Client-ID {}'.format(client_id)}
    timeout = 5

    # Query.
    app.info('querying {}'.format(url))
    try:
        response = requests.get(url, headers=headers, timeout=timeout)
    except (requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout, requests.Timeout) as exc:
        raise APIError('timed out waiting for reply from {}: {}'.format(url, str(exc)), app)
    except requests.ConnectionError as exc:
        raise APIError('unable to connect to {}: {}'.format(url, str(exc)), app)
    app.debug2('Imgur API responded with: %s', response.text)

    # Parse JSON.
    try:
        parsed = response.json()
    except ValueError:
        raise APIError('failed to parse JSON from {}'.format(url), app)

    # Verify data.
    if not parsed.get('success'):
        if 'data' not in parsed:
            message = 'no "data" key in JSON'
        elif 'error' not in parsed['data']:
            message = 'no "error" key in JSON'
        else:
            message = parsed['data']['error']
        raise APIError('query unsuccessful from {}: {}'.format(url, message), app)

    return parsed