Skip to content

Commit

Permalink
Add support for calling APIs that return xml (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbirddog authored Feb 21, 2024
1 parent b79938f commit 31e76be
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 22 deletions.
13 changes: 12 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ python = "^3.9"
requests = "^2.28.2"
spiffworkflow-connector-command = {git = "https://github.com/sartography/spiffworkflow-connector-command.git", rev = "main"}
# spiffworkflow-connector-command = {develop = true, path = "../spiffworkflow-connector-command"}
xmltodict = "^0.13.0"



Expand Down
5 changes: 4 additions & 1 deletion src/connector_http/commands/get_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ def __init__(self,
basic_auth_password: str | None = None,
attempts: int | None = None,
):
HttpRequestBase.__init__(self, url=url, headers=headers, basic_auth_username=basic_auth_username, basic_auth_password=basic_auth_password)
HttpRequestBase.__init__(self, url=url,
headers=headers,
basic_auth_username=basic_auth_username,
basic_auth_password=basic_auth_password)

self.params = params or {}

Expand Down
11 changes: 9 additions & 2 deletions src/connector_http/http_request_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from collections.abc import Callable

import requests # type: ignore
import xmltodict
from spiffworkflow_connector_command.command_interface import CommandErrorDict
from spiffworkflow_connector_command.command_interface import CommandResponseDict
from spiffworkflow_connector_command.command_interface import ConnectorProxyResponseDict
Expand Down Expand Up @@ -103,19 +104,25 @@ def log(msg: str) -> None:

if http_response is not None:
command_response = {"raw_response": http_response.text}
content_type = http_response.headers.get("Content-Type", "")
# this string can include modifiers like UTF-8, which is why it's not using ==
if "application/json" in http_response.headers.get("Content-Type", ""):
if "application/json" in content_type:
try:
command_response = json.loads(http_response.text)
except Exception as e:
error = self._create_error_from_exception(exception=e, http_response=http_response)
elif "application/xml" in content_type or "text/xml" in content_type:
try:
command_response = xmltodict.parse(http_response.text)
except Exception as e:
error = self._create_error_from_exception(exception=e, http_response=http_response)
log("Did parse http_response")

if status >= 400 and error is None:
error = self._create_error(error_code=f"HttpError{status}", http_response=http_response)

return_response: CommandResponseDict = {
"body": json.dumps(command_response),
"body": command_response,
"mimetype": mimetype,
"http_status": status,
}
Expand Down
6 changes: 3 additions & 3 deletions tests/connector_http/unit/test_delete_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_delete_html_from_url(self) -> None:
response = request.execute(None, {})
assert mock_request.call_count == 1

assert response["command_response"]["body"] == json.dumps({"raw_response": return_html})
assert response["command_response"]["body"] == {"raw_response": return_html}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -35,7 +35,7 @@ def test_delete_json_from_url(self) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -53,7 +53,7 @@ def test_delete_can_handle_500(self, sleepless: Any) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 500
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is not None
Expand Down
42 changes: 39 additions & 3 deletions tests/connector_http/unit/test_get_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_get_html_from_url(self) -> None:
response = request.execute(None, {})

assert response is not None
assert response["command_response"]["body"] == json.dumps({"raw_response": return_html})
assert response["command_response"]["body"] == {"raw_response": return_html}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -34,7 +34,43 @@ def test_get_json_from_url(self) -> None:
response = request.execute(None, {})

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
assert response["spiff__logs"] is not None
assert len(response["spiff__logs"]) > 0

def test_get_application_xml_from_url(self) -> None:
request = GetRequestV2(url="http://example.com")
return_xml = "<hey>we_return</hey>"
with patch("requests.get") as mock_request:
mock_request.return_value.status_code = 200
mock_request.return_value.ok = True
mock_request.return_value.headers = {"Content-Type": "application/xml"}
mock_request.return_value.text = return_xml
response = request.execute(None, {})

assert response is not None
assert response["command_response"]["body"] == {"hey": "we_return"}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
assert response["spiff__logs"] is not None
assert len(response["spiff__logs"]) > 0

def test_get_text_xml_from_url(self) -> None:
request = GetRequestV2(url="http://example.com")
return_xml = "<hey>we_return</hey>"
with patch("requests.get") as mock_request:
mock_request.return_value.status_code = 200
mock_request.return_value.ok = True
mock_request.return_value.headers = {"Content-Type": "text/xml"}
mock_request.return_value.text = return_xml
response = request.execute(None, {})

assert response is not None
assert response["command_response"]["body"] == {"hey": "we_return"}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -52,7 +88,7 @@ def test_get_can_handle_500(self, sleepless: Any) -> None:
assert mock_request.call_count == 3

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 500
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is not None
Expand Down
6 changes: 3 additions & 3 deletions tests/connector_http/unit/test_head_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_head_html_from_url(self) -> None:
response = request.execute(None, {})

assert response is not None
assert response["command_response"]["body"] == json.dumps({"raw_response": return_html})
assert response["command_response"]["body"] == {"raw_response": return_html}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -34,7 +34,7 @@ def test_head_json_from_url(self) -> None:
response = request.execute(None, {})

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -52,7 +52,7 @@ def test_head_can_handle_500(self, sleepless: Any) -> None:
assert mock_request.call_count == 3

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 500
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is not None
Expand Down
6 changes: 3 additions & 3 deletions tests/connector_http/unit/test_patch_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_patch_html_from_url(self) -> None:
response = request.execute(None, {})
assert mock_request.call_count == 1

assert response["command_response"]["body"] == json.dumps({"raw_response": return_html})
assert response["command_response"]["body"] == {"raw_response": return_html}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -35,7 +35,7 @@ def test_patch_json_from_url(self) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -53,7 +53,7 @@ def test_patch_can_handle_500(self, sleepless: Any) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 500
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is not None
Expand Down
6 changes: 3 additions & 3 deletions tests/connector_http/unit/test_post_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_post_html_from_url(self) -> None:
response = request.execute(None, {})
assert mock_request.call_count == 1

assert response["command_response"]["body"] == json.dumps({"raw_response": return_html})
assert response["command_response"]["body"] == {"raw_response": return_html}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -35,7 +35,7 @@ def test_post_json_from_url(self) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -53,7 +53,7 @@ def test_post_can_handle_500(self, sleepless: Any) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 500
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is not None
Expand Down
6 changes: 3 additions & 3 deletions tests/connector_http/unit/test_put_request_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_put_html_from_url(self) -> None:
response = request.execute(None, {})
assert mock_request.call_count == 1

assert response["command_response"]["body"] == json.dumps({"raw_response": return_html})
assert response["command_response"]["body"] == {"raw_response": return_html}
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -35,7 +35,7 @@ def test_put_json_from_url(self) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 200
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is None
Expand All @@ -53,7 +53,7 @@ def test_put_can_handle_500(self, sleepless: Any) -> None:
assert mock_request.call_count == 1

assert response is not None
assert response["command_response"]["body"] == json.dumps(return_json)
assert response["command_response"]["body"] == return_json
assert response["command_response"]["http_status"] == 500
assert response["command_response"]["mimetype"] == "application/json"
assert response["error"] is not None
Expand Down

0 comments on commit 31e76be

Please sign in to comment.