This file is indexed.

/usr/lib/python3/dist-packages/beanbag/v2.py is in python3-beanbag 1.9.2-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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/usr/bin/env python

# Copyright (c) 2014 Red Hat, Inc. and/or its affiliates.
# Copyright (c) 2015 Anthony Towns
# Written by Anthony Towns <aj@erisian.com.au>
# See LICENSE file.

from .namespace import HierarchialNS
from .bbexcept import BeanBagException
from .attrdict import AttrDict

import requests

try:
    import json
except ImportError:
    import simplejson as json


__all__ = ['BeanBag', 'Request', 'verb', 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE']
__version__ = '2.0.0'


def verb(verbname):
    """Construct a BeanBag compatible verb function

       :param verbname: verb to use (GET, POST, etc)
    """

    def do(url, body=None):
        base, path = ~url
        req = base.encode(body)
        res = base.make_request(path, verbname, req)
        return base.decode(res)

    do.__name__ = verbname
    do.__doc__ = "%s verb function" % (verbname,)
    return do

GET = verb("GET")
HEAD = verb("HEAD")
POST = verb("POST")
PUT = verb("PUT")
PATCH = verb("PATCH")
DELETE = verb("DELETE")


class Request(AttrDict):
    def __init__(self, **kwargs):
        """Create a Request object

           Request objects act as placeholders for the arguments to
           the requests() function of the requests.Session being used.
           They are used as the interface between the encode() and
           make_request() functions, and may also be used by the API
           caller.

           NB: A Request object is only suitable for one use, as it may
           be modified in-place during the request. For this reason,
           __init__ makes a (shallow) copy of all the keyword arguments
           supplied rather than using them directly.
        """

        for badarg in ["method", "url", "params"]:
            if badarg in kwargs:
                raise TypeError("__init__() got forbidden keyword argument '%s'" % (badarg,))

        d = {}
        for k, v in kwargs.items():
            if isinstance(v, list):
                v = v[:]
            elif isinstance(v, dict):
                v = v.copy()
            d[k] = v
        (~AttrDict).__init__(self, d)


class BeanBag(HierarchialNS):
    mime_json = "application/json"

    def __init__(self, base_url, ext="", session=None, use_attrdict=True):
        """Create a BeanBag referencing a base REST path.

           :param base_url: the base URL prefix for all resources
           :param ext: extension to add to resource URLs, eg ".json"
           :param session: requests.Session instance used for this API. Useful
                  to set an auth procedure, or change verify parameter.
           :param use_attrdict: if true, ``decode()`` will wrap dicts and
                  lists in a ``beanbag.attrdict.AttrDict`` for syntactic
                  sugar.
        """

        if session is None:
            session = requests.Session()

        self.base_url = base_url.rstrip("/") + "/"
        self.ext = ext

        self.session = session
        self.use_attrdict = use_attrdict

    def encode(self, body):
        """Convert a python object into a beanbag.Request object.

           This function converts the user provided body object (or None
           when there is no body) into a requests.Request object, by
           encoding it as JSON string. (Note that the url and method
           members of the Request are provided later by the

           :param body: provided by the API user, usually a dict or None
        """

        if isinstance(body, Request):
            req = body
        elif body is None:
            req = Request(data=None, headers={"Accept": self.mime_json})
        else:
            if isinstance(body, AttrDict):
                body = +body
            req = Request(data=json.dumps(body),
                    headers={"Accept": self.mime_json,
                        "Content-Type": self.mime_json})
        return req

    def decode(self, response):
        """Converts a requests.Response object to a python object

           This function converts the REST API's response back into a
           python object by decoding it from JSON (or raises an exception
           if the response indicates an error).

           :param response: requests.Response object
        """

        if response.status_code < 200 or response.status_code >= 300:
            raise BeanBagException(response,
                    "Bad response code: %d" % (response.status_code,))

        if not response.content:
            return None

        res_content = response.headers.get("content-type", None)
        if res_content is None:
            pass
        elif res_content.split(";", 1)[0] == self.mime_json:
            pass
        else:
            raise BeanBagException(response,
                    "Bad content-type in response (Content-Type: %s; wanted %s)"
                                     % (res_content.split(";", 1)[0],
                                         self.mime_json))
        try:
            obj = json.loads(response.text or response.content)
        except:
            raise BeanBagException(response, "Could not decode response")

        if self.use_attrdict:
            if isinstance(obj, dict) or isinstance(obj, list):
                obj = AttrDict(obj)

        return obj

    def baseurl_params(self, path):
        """Construct the base URL of a resource (excluding URL params)"""

        url, params = path
        return ("%s%s%s" % (self.base_url, url, self.ext)), params

    def str(self, path):
        """Obtain the URL of a resource"""

        url, params = self.baseurl_params(path)
        if params:
            url = "%s?%s" % (url, ";".join("%s=%s" % (str(k), str(v))
                        for k, v in params.items() if v is not None))
        return url

    def path(self):
        return ("", {})

    def attr(self, attr):
        """Special processing for attribute access

           This converts ._ to a trailing slash.
        """

        if attr == "_":
            attr = "/"
        return str(attr)

    def _get(self, path, el):
        url, params = path
        el = str(el).lstrip("/")
        if url == "":
            newurl = el
        else:
            newurl = url.rstrip("/") + "/" + el
        return (newurl, params)

    def call(self, path, *args, **kwargs):
        """Set URL parameters"""

        url, params = path
        newparams = params.copy()
        for a in tuple(args) + (kwargs,):
            for k, v in a.items():
                if v is not None:
                    newparams[k] = v
                elif k in newparams:
                    del newparams[k]

        return self.namespace((url, newparams))

    def invert(self, path):
        """Provide access to the base/path via the namespace object

           .. code::

              bb = BeanBag(...)
              base, path = ~bb.foo
              assert isinstance(base, BeanBagBase)

           This is the little bit of glue needed so that it's possible to
           call methods defined in BeanBagBase directly rather than just
           the operators BeanBag supports.
        """

        return self, path

    def make_request(self, path, verb, request):
        """Make a REST request to a resource"""

        url, params = self.baseurl_params(path)

        assert isinstance(request, Request)
        request = +request   # convert to dictionary

        return self.session.request(
                method=verb, url=url, params=params, **request)