def test_dump_response_fails_without_request(self): """Show that a response without a request raises a ValueError.""" del self.response.request assert hasattr(self.response, 'request') is False with pytest.raises(ValueError): dump.dump_response(self.response)
def _request(self, prepped_request, operation): """ Wrapper for the low-level Request action. Only low-level error handling. Args: prepped_request (Request): Prepared request for the operation. Returns: Operation Result object. """ stream = False if operation['dl_path']: stream = True try: res = self._session.send(prepped_request, stream=stream) except (requests.exceptions.RequestException) as rex: raise UnexpectedRequestError(rex.request, rex.response) # req_headers = dump_message_headers(res.request) # self._log.debug(req_headers) if is_multipart(res.request): res.request.body = '<< multipart body suppressed >>' if 200 <= res.status_code <= 299: if operation['dl_path'] is None: self._log.debug(dump.dump_response(res)) else: self._log.debug(res.status_code) self._log.debug(res.headers) return OperationResult(res.text, res, self, operation) else: self._log.info(dump.dump_response(res)) return OperationErrorResult(res.text, res)
def test_agent_command_start_unicast_by_home_page_url(self): cmd = "echo 1" # get eureka apps agent headers = {"Content-Type": "application/json"} response = requests.get( f"{self.home_url}:{self.server_port_ext}/eureka/apps/agent", headers=headers, auth=(self.username, self.password)) # print(dump.dump_response(response)) body = response.json() self.assertEqual(response.status_code, 200) self.assertEqual(len(body.get('description')), 1) # send unicast teststart request and check the results agent_apps = body.get('description') for i, item in enumerate(agent_apps): headers = { 'HomePageUrl': item.get('homePageUrl'), "Content-Type": "application/json" } # send unicast message to the agents with the ip:port response = requests.post( f"{self.home_url}:{self.server_port_ext}/agents/commands", data=cmd, headers=headers, auth=(self.username, self.password)) body = response.json() print(dump.dump_response(response)) self.assertEqual(response.status_code, 200) self.assertEqual(len(body.get('description')), 1) self.assertIsInstance( body.get('description')[0].get('description').get( 'commands').get(cmd), dict)
def test_teststop_p(self): test_id = "100" data_payload = f"sleep 7 \n sleep 3600 \n sleep 3601" commands = list(map(lambda x: x.strip(), data_payload.split("\n"))) headers = {'Content-type': 'text/plain'} response = requests.post( self.server + f"/test/{test_id}", data=f"{data_payload}", headers=headers) body = response.json() self.assertEqual(response.status_code, 200) self.assertEqual(body.get('message'), test_id) time.sleep(2) response = requests.get(self.server + "/test") body = response.json() self.assertEqual(body.get('message').get("id"), test_id) self.assertEqual(body.get('message').get("started"), "true") self.assertEqual(body.get('message').get("finished"), "false") self.assertEqual(body.get('message').get("commands").get(commands[0]).get("status"), "in progress") self.assertEqual(body.get('message').get("commands").get(commands[1]).get("status"), "scheduled") self.assertEqual(body.get('message').get("commands").get(commands[2]).get("status"), "scheduled") time.sleep(2) response = requests.delete(self.server + "/test") self.assertEqual(response.status_code, 200) body = response.json() self.assertEqual(body.get('message'), test_id) response = requests.get(self.server + "/test") print(dump.dump_response(response)) self.assertEqual(response.status_code, 200) body = response.json() # self.assertEqual(body.get('message').get("finished"), "true") self.assertEqual(body.get('message').get("id"), f"{test_id}")
def post_as_form(self, url, formdata, auth=None): """ Performs a POST request with form-data, expecting to receive JSON. This method is used in the OAuth2 token exchange and thus doesn't request fhir+json. :throws: Exception on HTTP status >= 400 :returns: The response object """ headers = { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'Accept': 'application/json', } stime = datetime.now() res = self.session.post(url, data=formdata, auth=auth) if logger.isEnabledFor(logging.DEBUG): logger.debug('SMART SERVER:{1}{0}'.format(dump.dump_response(res), LINE_SEP)) logger.info( 'method={} request_url={} x_request_id={} status={} response_time={:.3f} total_time={:.3f}' .format( res.request.method, res.request.url, res.headers.get('X-Request-Id'), res.headers.get('Status'), float( res.headers.get( 'X-Runtime', float(res.headers.get('Server-Response-Time', '0.0')) / 1000)), (datetime.now() - stime).total_seconds(), )) self.raise_for_status(res) return res
def request_json(self, path, nosign=False): """ Perform a request for JSON data against the server's base with the given relative path. :param str path: The path to append to `base_uri` :param bool nosign: If set to True, the request will not be signed :throws: Exception on HTTP status >= 400 :returns: Decoded JSON response """ headers = {'Accept': 'application/json'} stime = datetime.now() res = self._get(path, headers, nosign) if logger.isEnabledFor(logging.DEBUG): logger.debug('SMART SERVER:{1}{0}'.format(dump.dump_response(res), LINE_SEP)) logger.info( 'method={} request_url={} x_request_id={} status={} response_time={:.3f} total_time={:.3f}' .format( res.request.method, res.request.url, res.headers.get('X-Request-Id'), res.headers.get('Status'), float( res.headers.get( 'X-Runtime', float(res.headers.get('Server-Response-Time', '0.0')) / 1000)), (datetime.now() - stime).total_seconds(), )) return res.json()
def test_proxy_behaviour(self): with requests_mock.Mocker() as m: m.get( "http://foo.svc", status_code=200, headers={"Content-Type": "application/json"}, text="success", ) raw = dump.dump_response( requests.get("http://foo.svc"), request_prefix="", response_prefix="@@@", ) split = raw.split(b"@@@") raw_request = split[0] expected_response = HTTPResponse(b"".join(split[1:])) raw_request handler = TestableHandler(raw_request, (0, 0), None) write_file = io.BytesIO() handler.test(write_file) write_file.seek(0) response = HTTPResponse(write_file.read()) self.assertEqual(response.Status_Code, expected_response.Status_Code) self.assertEqual(response.Content_Type, expected_response.Content_Type) self.assertEqual(response.load, expected_response.load)
def check_response_status(cls, response): """Raise this exception if the response status is not ok.""" try: response.raise_for_status() except HTTPError as err: data = dump.dump_response(response) cls.logger.info("Unexpected HTTP response\n{}".format( data.decode('utf-8'))) message = "HTTP status is {:d}, not ok".format( response.status_code) raise cls(message) from err
def _query_data(self, resource, startDate, endDate): self.session.headers.update({'User-agent': "mylinky"}) # note: payload is useless for yearly resource payload = { '_lincspartdisplaycdc_WAR_lincspartcdcportlet_dateDebut': startDate.strftime("%d/%m/%Y"), '_lincspartdisplaycdc_WAR_lincspartcdcportlet_dateFin': endDate.strftime("%d/%m/%Y") } params = { 'p_p_id': 'lincspartdisplaycdc_WAR_lincspartcdcportlet', 'p_p_lifecycle': 2, 'p_p_state': 'normal', 'p_p_mode': 'view', 'p_p_resource_id': resource, 'p_p_cacheability': 'cacheLevelPage', 'p_p_col_id': 'column-1', 'p_p_col_pos': 1, 'p_p_col_count': 3 } log.info("Sending data request for resource %s (%s - %s)" % (resource, startDate, endDate)) resp = self.session.post(self.url, data=payload, params=params, allow_redirects=False) if 300 <= resp.status_code < 400: # It appears that it is frequent to get first a 302, even if the request is correct # #nocomment resp = self.session.post(self.url, data=payload, params=params, allow_redirects=False) log.debug("resp: %s" % dump.dump_response(resp).decode('utf-8')) body = resp.json() if body["etat"]["valeur"] == "erreur": raise DataException("Error on server when retrieving data: %s" % body["etat"]["erreurText"] if "erreurText" in body["etat"] else "n/a") if body["etat"]["valeur"] not in ["termine"]: raise DataException("Invalid response state code '%s'" % body["etat"]["valeur"]) return body["graphe"]
def call(self, title: str = '', body: str = ''): try: rsp = requests.post(f'{self.host}:{self.port}/record', json={ 'title': title, 'body': body }, timeout=2) if rsp.status_code - 400 >= 0: data = dump.dump_response(rsp) logger.warning(data) except Exception as e: logger.warning(f"Request failed due to [{e}]")
def _call(self, url, action, data): # Get HTTP verb action method (client.get()) method_to_call = getattr(self.client, action) resp = method_to_call(url, json=data) print("") print("Response:") # Log output to file log and console resp_dump = dump.dump_response(resp) self.logger.debug(data) self.logger.info(resp_dump.decode('utf-8')) return resp
def test_dump_response(self): session = requests.Session() recorder = get_betamax(session) with recorder.use_cassette('simple_get_request'): response = session.get('https://httpbin.org/get') arr = dump.dump_response(response) assert b'< GET /get HTTP/1.1\r\n' in arr assert b'< Host: httpbin.org\r\n' in arr # NOTE(sigmavirus24): The ? below is only because Betamax doesn't # preserve which HTTP version the server reports as supporting. # When not using Betamax, there should be a different version # reported. assert b'> HTTP/? 200 OK\r\n' in arr assert b'> Content-Type: application/json\r\n' in arr
def test_rendwithenv_endpoint(self, template, variables): payload = {'DATABASE': 'mysql56', 'IMAGE': 'latest'} headers = {'Content-type': 'application/json'} response = requests.post(self.service + f"/render/{template}/{variables}", data=json.dumps(payload), headers=headers, auth=(self.username, self.password)) print(dump.dump_response(response)) self.assertEqual(response.status_code, 200) body = yaml.safe_load(response.text) self.assertEqual(len(body.get("services")), 2) self.assertEqual(int(body.get("version")), 3)
def test_number_of_ES_messages(self): # 2 messages each microservice boot # 6 messages api request-response # 3 fluentd booting # 3 from java agent expected_no_of_ES_messages = (1 + 1) + (2 + 2 + 2) + (1 + 1 + 1) + (2 + 1) response = requests.get(self.server + "/fluentd*/_search?size=1000&&sort=@timestamp") body = response.json() number_of_ES_messages = body.get("hits").get("total").get("value") print(dump.dump_response(response)) self.assertEqual(response.status_code, 200) self.assertEqual(number_of_ES_messages, expected_no_of_ES_messages)
def put_json(self, path, resource_json, nosign=False): """ Performs a PUT request of the given JSON, which should represent a resource, to the given relative path. :param str path: The path to append to `base_uri` :param dict resource_json: The JSON representing the resource :param bool nosign: If set to True, the request will not be signed :throws: Exception on HTTP status >= 400 :returns: The response object """ url = urlparse.urljoin(self.base_uri, path) headers = { 'Content-type': FHIRJSONMimeType, 'Accept': FHIRJSONMimeType, 'Accept-Charset': 'UTF-8', } if resource_json.get('id', None) is not None: headers['If-Match'] = 'W/"{}"'.format( resource_json.get('meta').get('versionId')) if not nosign and self.auth is not None and self.auth.can_sign_headers( ): headers = self.auth.signed_headers(headers) # perform the request but intercept 401 responses, raising our own Exception stime = datetime.now() res = self.session.put(url, headers=headers, data=json.dumps(resource_json)) if logger.isEnabledFor(logging.DEBUG): logger.debug('SMART SERVER:{1}{0}'.format(dump.dump_response(res), LINE_SEP)) logger.info( 'method={} request_url={} x_request_id={} status={} response_time={:.3f} total_time={:.3f}' .format( res.request.method, res.request.url, res.headers.get('X-Request-Id'), res.headers.get('Status'), float( res.headers.get( 'X-Runtime', float(res.headers.get('Server-Response-Time', '0.0')) / 1000)), (datetime.now() - stime).total_seconds(), )) self.raise_for_status(res) return res
def test_about_endpoint_discovery_broadcast_to_agents_p(self): headers = {'Token': 'None'} response = requests.get(self.server_discovery + f"/{self.compose_id}/agents/about", headers=headers) print(dump.dump_response(response)) body = response.json() self.assertEqual(response.status_code, 200) self.assertIsInstance( body.get('description')[0].get('description'), dict) self.assertEqual( body.get('description')[0].get('message'), ErrorCodes.HTTP_CODE.get(Constants.SUCCESS)) self.assertEqual( body.get('description')[0].get('code'), Constants.SUCCESS) self.assertIsNotNone(body.get('description')[0].get('timestamp'))
def raise_response_error(r): if r.status_code >= 400: print("==== Response Debugging ====") print("##Request Headers", r.request.headers) # extract content type ct = r.headers["content-type"].split(";")[0] if ct == ContentType.JSON.value: dump = dump_response(r) print(dump) print("##Response:", dump.decode("UTF-8")) err = dacite.from_dict(data_class=Error, data=r.json()) print(err) elif ct == ContentType.NDJSON.value: decoded = ndjson.loads(r.text) print("##Response:", decoded) r.raise_for_status()
def create_from_response(cls, log_type, url, response, classifier=None, channel=None, ticketer=None, request_time=None): org = (classifier or channel or ticketer).org is_error = response.status_code >= 400 data = dump.dump_response( response, request_prefix=cls.REQUEST_DELIM.encode("utf-8"), response_prefix=cls.RESPONSE_DELIM.encode("utf-8"), ).decode("utf-8") # first build our array of request lines, our last item will also contain our response lines request_lines = data.split(cls.REQUEST_DELIM) # now split our response lines from the last request line response_lines = request_lines[-1].split(cls.RESPONSE_DELIM) # and clean up the last and first item appropriately request_lines[-1] = response_lines[0] response_lines = response_lines[1:] request = "".join(request_lines) response = "".join(response_lines) return cls.objects.create( org=org, log_type=log_type, url=url, request=request, response=response, is_error=is_error, created_on=timezone.now(), request_time=request_time, classifier=classifier, channel=channel, ticketer=ticketer, )
def login(self, username, password): self.session.headers.update({'User-agent': "mylinky"}) payload = { 'IDToken1': username, 'IDToken2': password, 'SunQueryParamsString': base64.b64encode(b'realm=particuliers'), 'encoded': 'true', 'gx_charset': 'UTF-8' } log.info("Sending login request for user %s" % username) resp = self.session.post(self.url, data=payload, allow_redirects=False) log.debug("resp: %s" % dump.dump_response(resp).decode('utf-8')) log.debug("cookies: %s" % resp.cookies) if not 'iPlanetDirectoryPro' in resp.cookies: raise LoginException("Login unsuccessful. Check your credentials.") return [ c for c in resp.cookies]
def test_dump_response_uses_provided_bytearray(self): """Show that users providing bytearrays receive those back.""" self.configure_request( url='http://example.com/', method='GET', ) self.configure_response( url='https://example.com/redirected', content=b'foobarbogus', reason=b'OK', ) self.configure_httpresponse( headers={'Content-Type': 'application/json'}, reason=b'OK', status=201, ) arr = bytearray() retarr = dump.dump_response(self.response, data_array=arr) assert retarr is arr
def responseHook(resp, *args, **kwargs): global dumpRequestInfo, dumpResponseInfo, printAndDumpRequestsToFiles try: if dumpRequestInfo or printAndDumpRequestsToFiles: requestDumpFilenamePrefix = '' if printAndDumpRequestsToFiles: requestDumpFilenamePrefix = "request-body" data = dump.dump_request(resp, b' ', b' ', None, requestDumpFilenamePrefix) print(data.decode('utf-8'), file=sys.stderr) if dumpResponseInfo: respdata = dump.dump_response(resp, b' ', b' ') print(respdata.decode('utf-8'), file=sys.stderr) except Exception as e: print(str(e), file=sys.stderr)
def delete_json(self, path, nosign=False): """ Issues a DELETE command against the given relative path, accepting a JSON response. :param str path: The relative URL path to issue a DELETE against :param bool nosign: If set to True, the request will not be signed :returns: The response object """ url = urlparse.urljoin(self.base_uri, path) headers = { 'Accept': FHIRJSONMimeType, 'Accept-Charset': 'UTF-8', } if not nosign and self.auth is not None and self.auth.can_sign_headers( ): headers = self.auth.signed_headers(headers) # perform the request but intercept 401 responses, raising our own Exception stime = datetime.now() res = self.session.delete(url) if logger.isEnabledFor(logging.DEBUG): logger.debug('SMART SERVER:{1}{0}'.format(dump.dump_response(res), LINE_SEP)) logger.info( 'method={} request_url={} x_request_id={} status={} response_time={:.3f} total_time={:.3f}' .format( res.request.method, res.request.url, res.headers.get('X-Request-Id'), res.headers.get('Status'), float( res.headers.get( 'X-Runtime', float(res.headers.get('Server-Response-Time', '0.0')) / 1000)), (datetime.now() - stime).total_seconds(), )) self.raise_for_status(res) return res
def _get(self, path, headers={}, nosign=False): """ Issues a GET request. :returns: The response object """ assert self.base_uri and path url = urlparse.urljoin(self.base_uri, path) headers = { 'Accept': FHIRJSONMimeType, 'Accept-Charset': 'UTF-8', } if not nosign and self.auth is not None and self.auth.can_sign_headers( ): headers = self.auth.signed_headers(headers) # perform the request but intercept 401 responses, raising our own Exception stime = datetime.now() res = self.session.get(url, headers=headers) if logger.isEnabledFor(logging.DEBUG): logger.debug('SMART SERVER:{1}{0}'.format(dump.dump_response(res), LINE_SEP)) logger.info( 'method={} request_url={} x_request_id={} status={} response_time={:.3f} total_time={:.3f}' .format( res.request.method, res.request.url, res.headers.get('X-Request-Id'), res.headers.get('Status'), float( res.headers.get( 'X-Runtime', float(res.headers.get('Server-Response-Time', '0.0')) / 1000)), (datetime.now() - stime).total_seconds(), )) self.raise_for_status(res) return res
def from_response(cls, log_type, url, response, classifier=None): # remove once we have other types assert classifier is not None if classifier is not None: org = classifier.org is_error = response.status_code != 200 data = dump.dump_response( response, request_prefix=cls.REQUEST_DELIM, response_prefix=cls.RESPONSE_DELIM).decode("utf-8") # first build our array of request lines, our last item will also contain our response lines request_lines = data.split(cls.REQUEST_DELIM) # now split our response lines from the last request line response_lines = request_lines[-1].split(cls.RESPONSE_DELIM) # and clean up the last and first item appropriately request_lines[-1] = response_lines[0] response_lines = response_lines[1:] request = "".join(request_lines) response = "".join(response_lines) return HTTPLog( classifier=classifier, log_type=log_type, url=url, request=request, response=response, is_error=is_error, created_on=timezone.now(), org=org, )
def request_data(self, path, headers={}, nosign=False): """ Perform a data request data against the server's base with the given relative path. """ stime = datetime.now() res = self._get(path, None, nosign) if logger.isEnabledFor(logging.DEBUG): logger.debug('SMART SERVER:{1}{0}'.format(dump.dump_response(res), LINE_SEP)) logger.info( 'method={} request_url={} x_request_id={} status={} response_time={:.3f} total_time={:.3f}' .format( res.request.method, res.request.url, res.headers.get('X-Request-Id'), res.headers.get('Status'), float( res.headers.get( 'X-Runtime', float(res.headers.get('Server-Response-Time', '0.0')) / 1000)), (datetime.now() - stime).total_seconds(), )) return res.content
def check_response(self, response): if response.status_code != 200: data = dump.dump_response(response) print(data.decode('utf-8')) sys.exit()
def save_response(response, path): """Save an HTTP response to the path.""" with path.with_suffix(".txt").open("w") as f: data = dump.dump_response(response) print(data.decode("utf-8"), file=f)