diff --git a/poetry.lock b/poetry.lock
index 97275b8..ff0ced1 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -367,7 +367,18 @@ secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
+[[package]]
+name = "xmltodict"
+version = "0.13.0"
+description = "Makes working with XML feel like you are working with JSON"
+optional = false
+python-versions = ">=3.4"
+files = [
+ {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"},
+ {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"},
+]
+
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
-content-hash = "8c6425b085e3770b1f16ab27d7a59d79d841040dc3125f2be8eece93d6ffd25a"
+content-hash = "848238ed8d774980d2599d6865197ba62b5e05f66073815fe00671bdde3a43be"
diff --git a/pyproject.toml b/pyproject.toml
index b33df39..05a76c0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -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"
diff --git a/src/connector_http/commands/get_request_v2.py b/src/connector_http/commands/get_request_v2.py
index 12fe92b..436e65a 100644
--- a/src/connector_http/commands/get_request_v2.py
+++ b/src/connector_http/commands/get_request_v2.py
@@ -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 {}
diff --git a/src/connector_http/http_request_base.py b/src/connector_http/http_request_base.py
index 750b7f7..ed86048 100644
--- a/src/connector_http/http_request_base.py
+++ b/src/connector_http/http_request_base.py
@@ -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
@@ -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,
}
diff --git a/tests/connector_http/unit/test_delete_request_v2.py b/tests/connector_http/unit/test_delete_request_v2.py
index 39a1339..1acc58c 100644
--- a/tests/connector_http/unit/test_delete_request_v2.py
+++ b/tests/connector_http/unit/test_delete_request_v2.py
@@ -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
@@ -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
@@ -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
diff --git a/tests/connector_http/unit/test_get_request_v2.py b/tests/connector_http/unit/test_get_request_v2.py
index cf96500..99528fd 100644
--- a/tests/connector_http/unit/test_get_request_v2.py
+++ b/tests/connector_http/unit/test_get_request_v2.py
@@ -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
@@ -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 = "we_return"
+ 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 = "we_return"
+ 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
@@ -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
diff --git a/tests/connector_http/unit/test_head_request_v2.py b/tests/connector_http/unit/test_head_request_v2.py
index 1be7d03..df4a45a 100644
--- a/tests/connector_http/unit/test_head_request_v2.py
+++ b/tests/connector_http/unit/test_head_request_v2.py
@@ -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
@@ -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
@@ -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
diff --git a/tests/connector_http/unit/test_patch_request_v2.py b/tests/connector_http/unit/test_patch_request_v2.py
index 8a429e2..95387db 100644
--- a/tests/connector_http/unit/test_patch_request_v2.py
+++ b/tests/connector_http/unit/test_patch_request_v2.py
@@ -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
@@ -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
@@ -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
diff --git a/tests/connector_http/unit/test_post_request_v2.py b/tests/connector_http/unit/test_post_request_v2.py
index e2826d6..1a448f5 100644
--- a/tests/connector_http/unit/test_post_request_v2.py
+++ b/tests/connector_http/unit/test_post_request_v2.py
@@ -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
@@ -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
@@ -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
diff --git a/tests/connector_http/unit/test_put_request_v2.py b/tests/connector_http/unit/test_put_request_v2.py
index c66c3f4..221a0c9 100644
--- a/tests/connector_http/unit/test_put_request_v2.py
+++ b/tests/connector_http/unit/test_put_request_v2.py
@@ -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
@@ -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
@@ -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