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]
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'] )
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) ) )
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))