This file is indexed.

/usr/lib/python3/dist-packages/pydap/client.py is in python3-pydap 3.2.2+ds1-1ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
"""
Pydap client.

This module contains functions to access DAP servers. The most common use is to
open a dataset by its canonical URL, ie, without any DAP related extensions
like dds/das/dods/html. Here is an example:

    >>> from pydap.client import open_url
    >>> dataset = open_url("http://test.pydap.org/coads.nc")

This will return a `DatasetType` object, which is a container for lazy
evaluated objects. Data is downloaded automatically when arrays are sliced or
when sequences are iterated.

It is also possible to download data directly from a dods (binary) response.
This allows calling server-specific functions, like those supported by the
Ferret and the GrADS data servers:

    >>> from pydap.client import open_dods
    >>> dataset = open_dods(
    ...     "http://test.pydap.org/coads.nc.dods",
    ...     metadata=True)

Setting the `metadata` flag will also request the das response, populating the
dataset with the corresponding metadata.

If the dods response has already been downloaded, it is possible to open it as
if it were a remote dataset. Optionally, it is also possible to specify a das
response:

    >>> from pydap.client import open_file
    >>> dataset = open_file(
    ...     "/path/to/file.dods", "/path/to/file.das")  #doctest: +SKIP

Remote datasets opened with `open_url` can call server functions. Pydap has a
lazy mechanism for function call, supporting any function. Eg, to call the
`geogrid` function on the server:

    >>> dataset = open_url(
    ...     'http://test.opendap.org/dap/data/nc/coads_climatology.nc')
    >>> new_dataset = dataset.functions.geogrid(dataset.SST, 10, 20, -10, 60)
    >>> print(new_dataset.SST.SST.shape) #doctest: +SKIP
    (12, 12, 21)

"""

from io import open, BytesIO
from six.moves.urllib.parse import urlsplit, urlunsplit

from .model import DapType
from .lib import encode, DEFAULT_TIMEOUT
from .net import GET, raise_for_status
from .handlers.dap import DAPHandler, unpack_data, StreamReader
from .parsers.dds import build_dataset
from .parsers.das import parse_das, add_attributes


def open_url(url, application=None, session=None, output_grid=True,
             timeout=DEFAULT_TIMEOUT):
    """
    Open a remote URL, returning a dataset.

    set output_grid to False to retrieve only main arrays and
    never retrieve coordinate axes.
    """
    dataset = DAPHandler(url, application, session, output_grid,
                         timeout).dataset

    # attach server-side functions
    dataset.functions = Functions(url, application, session)

    return dataset


def open_file(dods, das=None):
    """Open a file downloaded from a `.dods` response, returning a dataset.

    Optionally, read also the `.das` response to assign attributes to the
    dataset.

    """
    dds = ''
    # This file contains both ascii _and_ binary data
    # Let's handle them separately in sequence
    # Without ignoring errors, the IO library will
    # actually read past the ascii part of the
    # file (despite our break from iteration) and
    # will error out on the binary data
    with open(dods, "rt", buffering=1, encoding='ascii',
              newline='\n', errors='ignore') as f:
        for line in f:
            if line.strip() == 'Data:':
                break
            dds += line
    dataset = build_dataset(dds)
    pos = len(dds) + len('Data:\n')

    with open(dods, "rb") as f:
        f.seek(pos)
        dataset.data = unpack_data(f, dataset)

    if das is not None:
        with open(das) as f:
            add_attributes(dataset, parse_das(f.read()))

    return dataset


def open_dods(url, metadata=False, application=None, session=None,
              timeout=DEFAULT_TIMEOUT):
    """Open a `.dods` response directly, returning a dataset."""
    r = GET(url, application, session, timeout=timeout)
    raise_for_status(r)

    dds, data = r.body.split(b'\nData:\n', 1)
    dds = dds.decode(r.content_encoding or 'ascii')
    dataset = build_dataset(dds)
    stream = StreamReader(BytesIO(data))
    dataset.data = unpack_data(stream, dataset)

    if metadata:
        scheme, netloc, path, query, fragment = urlsplit(url)
        dasurl = urlunsplit(
            (scheme, netloc, path[:-4] + 'das', query, fragment))
        r = GET(dasurl, application, session, timeout=timeout)
        raise_for_status(r)
        das = r.text
        add_attributes(dataset, parse_das(das))

    return dataset


class Functions(object):

    """Proxy for server-side functions."""

    def __init__(self, baseurl, application=None, session=None):
        self.baseurl = baseurl
        self.application = application
        self.session = session

    def __getattr__(self, attr):
        return ServerFunction(self.baseurl, attr, self.application,
                              self.session)


class ServerFunction(object):

    """A proxy for a server-side function.

    Instead of returning datasets, the function will return a proxy object,
    allowing nested requests to be performed on the server.

    """

    def __init__(self, baseurl, name, application=None, session=None):
        self.baseurl = baseurl
        self.name = name
        self.application = application
        self.session = None

    def __call__(self, *args):
        params = []
        for arg in args:
            if isinstance(arg, (DapType, ServerFunctionResult)):
                params.append(arg.id)
            else:
                params.append(encode(arg))
        id_ = self.name + '(' + ','.join(params) + ')'
        return ServerFunctionResult(self.baseurl, id_, self.application,
                                    self.session)


class ServerFunctionResult(object):

    """A proxy for the result from a server-side function call."""

    def __init__(self, baseurl, id_, application=None, session=None):
        self.id = id_
        self.dataset = None
        self.application = application
        self.session = session

        scheme, netloc, path, query, fragment = urlsplit(baseurl)
        self.url = urlunsplit((scheme, netloc, path + '.dods', id_, None))

    def __getitem__(self, key):
        if self.dataset is None:
            self.dataset = open_dods(self.url, True, self.application,
                                     self.session)
        return self.dataset[key]

    def __getattr__(self, name):
        return self[name]