Beispiel #1
0
    def execute_sql(self, return_id=False):
        query = self.query
        """:type: django.db.models.sql.subqueries.InsertQuery"""
        opts = query.get_meta()
        can_bulk = not return_id and self.connection.features.has_bulk_insert

        query_objs = query.objs
        if can_bulk:
            # bulk insert
            data = [{
                f.column: f.get_db_prep_save(getattr(
                    obj, f.attname) if query.raw else f.pre_save(obj, True),
                                             connection=self.connection)
                for f in query.fields
            } for obj in query_objs]

            json = {get_resource_name(query.model, many=True): data}
            response = self.connection.cursor().post(get_resource_path(
                self.query.model),
                                                     json=json)
            if response.status_code != 201:
                raise FakeDatabaseDbAPI2.ProgrammingError(
                    "error while creating %d %s.\n%s" %
                    (len(query_objs), opts.verbose_name,
                     response.json()['errors']))
            result_json = response.json()
            for old, new in zip(
                    query_objs, result_json[get_resource_name(query.model,
                                                              many=True)]):
                for field in opts.concrete_fields:
                    setattr(old, field.attname,
                            field.to_python(new[field.name]))
        else:
            result_json = None
            for obj in query_objs:
                data = {
                    f.column:
                    f.get_db_prep_save(getattr(obj, f.attname)
                                       if query.raw else f.pre_save(obj, True),
                                       connection=self.connection)
                    for f in query.fields
                }

                json = {get_resource_name(query.model, many=False): data}
                response = self.connection.cursor().post(get_resource_path(
                    self.query.model),
                                                         json=json)
                if response.status_code != 201:
                    raise FakeDatabaseDbAPI2.ProgrammingError(
                        "error while creating %s.\n%s" %
                        (obj, message_from_response(response)))
                result_json = response.json()
                new = result_json[get_resource_name(query.model, many=False)]
                for field in opts.concrete_fields:
                    setattr(obj, field.attname,
                            field.to_python(new[field.name]))

            if return_id and result_json:
                return result_json[get_resource_name(
                    query.model, many=False)][opts.pk.column]
Beispiel #2
0
 def get_token(self):
     """
     query the api to retrive a OAuth token
     :return: the token from the api
     :rtype: Token
     """
     conn = self.databasewrapper.cursor()
     params = {'grant_type': 'client_credentials'}
     # Get client credentials params
     response = conn.session.request(
         'POST',
         self.url_token,
         params=params,
         auth=(self.settings_dict['USER'], self.settings_dict['PASSWORD']),
         stream=False
     )
     if response.status_code != 200:
         raise ProgrammingError("unable to retrive the oauth token from %s: %s" %
                                (self.url_token,
                                 message_from_response(response))
                                )
     data = response.json()
     return Token(
         datetime.datetime.now() + datetime.timedelta(seconds=data['expires_in']),
         data['access_token'],
         data['token_type'],
         data['scope']
     )
Beispiel #3
0
 def raise_on_response_forbidden(self, response):
     if response.status_code == 403:
         raise FakeDatabaseDbAPI2.ProgrammingError(
             "Access to database is Forbidden for user %s on %s.\n%s" % (
                 self.settings_dict['USER'],
                 self.settings_dict['NAME'],
                 message_from_response(response)
             )
         )
Beispiel #4
0
 def raise_on_response(self, url, params, response):
     """
     raise a exception with a explicit message if the respones from the backend is not a 200, 202 or 204
     :param url:
     :param params:
     :param response:
     :return:
     """
     if response.status_code == 404:
         raise EmptyResultSet()
     if response.status_code == 204:
         raise EmptyResultSet()
     elif response.status_code != 200:
         raise ProgrammingError(
             "the query to the api has failed : GET %s/%s \n=> %s" %
             (self.connection.connection.url, build_url(
                 url, params), message_from_response(response)))
    def request(self, method, url, **kwargs):
        """
        wrapper for requests.Session.get

        :param unicode method: the method to use
        :param str url: the path relative to the current connexion
        :param dict[str, any]|byes params: (optional) Dictionary or bytes to append as GET parameters
        :param dict[str, any]|bytes data: (optional) Dictionary, bytes, or file-like object to send
            in the body
        :param headers: (optional) Dictionary of HTTP Headers to send with the
            :class:`Request`.
        :param cookies: (optional) Dict or CookieJar object to send with the
            :class:`Request`.
        :param files: (optional) Dictionary of ``'filename': file-like-objects``
            for multipart encoding upload.
        :param auth: (optional) Auth tuple or callable to enable
            Basic/Digest/Custom HTTP Auth.
        :param float|tuple[float, float] timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :rtype: requests.Response

        """
        kwargs.setdefault("allow_redirects", False)
        kwargs.setdefault("timeout", self.get_timeout())
        kwargs.setdefault('stream', False)

        assert not url.startswith("/"), "the url should not start with a «/»"
        if url != '' and not self.url.endswith('/'):
            url = '/' + url
        error = 0
        last_exception = None

        while error <= self.retry:
            try:
                real_url = self.url + url
                # to stay compatible with django_debug_toolbar, we must
                # call execute on the cursor return by the backend, since this one is replaced
                # by django-debug-toolbar to state the query.
                if self.backend:
                    execute = self.backend.cursor().execute
                else:
                    execute = self.execute
                response = execute("%s %s" % (method.upper(), real_url),
                                   dict(method=method, url=real_url, **kwargs))

            except Timeout as e:
                error += 1
                last_exception = e
            except ConnectionError as e:
                error += 1
                last_exception = e
            else:

                if self.auth and hasattr(self.auth,
                                         'raise_on_response_forbidden'):
                    self.auth.raise_on_response_forbidden(response)
                else:
                    if response.status_code in (403, 401):
                        raise FakeDatabaseDbAPI2.ProgrammingError(
                            "Access to database is Forbidden for user %s.\n%s"
                            %
                            (self.auth[0] if isinstance(self.auth, tuple) else
                             self.auth, message_from_response(response)))
                return response
        raise FakeDatabaseDbAPI2.OperationalError(
            "cound not connect to server: %s\nIs the API running on %s ? tried %d times"
            % (last_exception, self.url, error))