Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for calling APIs that return xml #7

Merged
merged 3 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading