Skip to content

Commit

Permalink
feat(response): possibility of placeholder vars in standard responses…
Browse files Browse the repository at this point in the history
… to improve error details
  • Loading branch information
KaiSchwarz-cnic committed May 7, 2020
1 parent 3100656 commit 393f20c
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 17 deletions.
8 changes: 5 additions & 3 deletions hexonet/apiconnector/apiclient.py
Expand Up @@ -265,16 +265,18 @@ def request(self, cmd):
newcmd = self.__autoIDNConvert(newcmd)

# request command to API
cfg = {
"CONNECTION_URL": self.__socketURL
}
data = self.getPOSTData(newcmd).encode('UTF-8')
secured = self.getPOSTData(newcmd, True).encode('UTF-8')
# TODO: 300s (to be sure to get an API response)
try:
headers = {
'User-Agent': self.getUserAgent()
}
if "REFERER" in self.__curlopts:
headers['Referer'] = self.__curlopts["REFERER"]
req = Request(self.__socketURL, data, headers)
req = Request(cfg["CONNECTION_URL"], data, headers)
if "PROXY" in self.__curlopts:
proxyurl = urlparse(self.__curlopts["PROXY"])
req.set_proxy(proxyurl.netloc, proxyurl.scheme)
Expand All @@ -285,7 +287,7 @@ def request(self, cmd):
body = rtm.getTemplate("httperror").getPlain()
if (self.__debugMode):
print((self.__socketURL, secured, "HTTP communication failed", body, '\n', '\n'))
return Response(body, newcmd)
return Response(body, newcmd, cfg)

def requestNextResponsePage(self, rr):
"""
Expand Down
10 changes: 9 additions & 1 deletion hexonet/apiconnector/response.py
Expand Up @@ -12,6 +12,7 @@
from hexonet.apiconnector.record import Record

import math
import re


class Response(RT, object):
Expand All @@ -20,8 +21,15 @@ class Response(RT, object):
Backend API response data in a useful way.
"""

def __init__(self, raw, cmd=None):
def __init__(self, raw, cmd=None, cfg={}):
super(Response, self).__init__(raw)

if re.search(r"\{[A-Z_]+\}", self._raw):
for key, value in cfg.items():
self._raw = self._raw.replace("{%s}" % (key), value)
self._raw = re.sub(r"\{[A-Z_]+\}", "", self._raw)
super(Response, self).__init__(self._raw)

# The API Command used within this request
self.__command = cmd
if (self.__command is not None) and ('PASSWORD' in self.__command):
Expand Down
22 changes: 11 additions & 11 deletions hexonet/apiconnector/responsetemplate.py
Expand Up @@ -18,30 +18,30 @@ class ResponseTemplate(object):
"""

def __init__(self, response=""):
descr = "Empty API response. Probably unreachable API end point"
#: Holds the response as plain text / string
self.__raw = response
self._raw = response
if (response is "") or (response is None):
self.__raw = "[RESPONSE]\r\nCODE=423\r\nDESCRIPTION=%s\r\nEOF\r\n" % (descr)
descr = "Empty API response. Probably unreachable API end point {CONNECTION_URL}"
self._raw = "[RESPONSE]\r\nCODE=423\r\nDESCRIPTION=%s\r\nEOF\r\n" % (descr)

# try/except to support old versions of python (python2.5)
try:
if isinstance(self.__raw, bytes):
self.__raw = self.__raw.decode("utf-8")
if isinstance(self._raw, bytes):
self._raw = self._raw.decode("utf-8")
except UnicodeError:
self.__raw = self.__raw.decode("latin1")
self._raw = self._raw.decode("latin1")
except BaseException:
self.__raw = self.__raw.decode("utf-8")
self._raw = self._raw.decode("utf-8")

if isinstance(response, dict):
raise TypeError('Type "dict" is not allowed for parameter "response". Use type "string" instead.')
else:
#: Holds the response as hash
self.__hash = RP.parse(self.__raw)
self.__hash = RP.parse(self._raw)

if ('CODE' not in self.__hash) or ('DESCRIPTION' not in self.__hash):
self.__raw = '[RESPONSE]\r\nCODE=423\r\nDESCRIPTION=Invalid API response. Contact Support\r\nEOF\r\n'
self.__hash = RP.parse(self.__raw)
self._raw = '[RESPONSE]\r\nCODE=423\r\nDESCRIPTION=Invalid API response. Contact Support\r\nEOF\r\n'
self.__hash = RP.parse(self._raw)

def getCode(self):
"""
Expand All @@ -59,7 +59,7 @@ def getPlain(self):
"""
Returns the plain API response
"""
return self.__raw
return self._raw

def getQueuetime(self):
"""
Expand Down
4 changes: 3 additions & 1 deletion hexonet/apiconnector/responsetemplatemanager.py
Expand Up @@ -29,7 +29,9 @@ def __new__(cls):
ResponseTemplateManager.__templates = {
"404": rtm.generateTemplate("421", "Page not found"),
"500": rtm.generateTemplate("500", "Internal server error"),
"empty": rtm.generateTemplate("423", "Empty API response. Probably unreachable API end point"),
"empty": rtm.generateTemplate(
"423", "Empty API response. Probably unreachable API end point {CONNECTION_URL}"
),
"error": rtm.generateTemplate("421", "Command failed due to server error. Client should try again"),
"expired": rtm.generateTemplate("530", "SESSION NOT FOUND"),
"httperror": rtm.generateTemplate("421", "Command failed due to HTTP communication error"),
Expand Down
8 changes: 8 additions & 0 deletions tests/test_response.py
@@ -1,6 +1,7 @@
from hexonet.apiconnector.response import Response as R
import hexonet.apiconnector.responseparser as RP
from hexonet.apiconnector.responsetemplatemanager import ResponseTemplateManager as RTM
import re


def test_responsemethods():
Expand Down Expand Up @@ -40,6 +41,13 @@ def test_responsemethods():
r = R(RP.serialize(h))
assert r.getFirstRecordIndex() == 0

# #.constructor [place holder replacements]
r = R("")
assert re.search(r"\{[A-Z_]+\}", r.getDescription()) is None

r = R("", {"COMMAND": "StatusAccount"}, {"CONNECTION_URL": "123HXPHFOUND123"})
assert re.search(r"123HXPHFOUND123", r.getDescription()) is not None

# #.getCommandPlain()
# case 1
r = R("", {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_responsetemplate.py
Expand Up @@ -7,7 +7,7 @@ def test_responsetemplatemethods():
assert tpl.getCode() == 423
assert tpl.getDescription() == "Invalid API response. Contact Support"

descr = "Empty API response. Probably unreachable API end point"
descr = "Empty API response. Probably unreachable API end point {CONNECTION_URL}"
# check instance [raw empty string]
tpl = ResponseTemplate()
assert tpl.getCode() == 423
Expand Down

0 comments on commit 393f20c

Please sign in to comment.