From 819b0126b902b94b73d5858e7548a607fa3a161a Mon Sep 17 00:00:00 2001
From: Nicholas Felt <nicholas.felt@tektronix.com>
Date: Tue, 14 Nov 2023 17:25:46 -0800
Subject: [PATCH] feat(rest_api_device): Enable sending raw data for restful
 api devices. (#107)

Co-authored-by: Collin Charvat <91292030+c3charvat@users.noreply.github.com>
Signed-off-by: qthompso <quinn.thompson@tektronix.com>
---
 CHANGELOG.md                                  |  4 ++
 .../drivers/api/rest_api/rest_api_device.py   | 38 ++++++++++++++++---
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4348b6812..41bf50890 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,10 @@ ______________________________________________________________________
 
 Things to be included in the next release go here.
 
+### Added
+
+- Added an option to send raw data for RESTful API devices
+
 ### Changed
 
 - Updated the package classifiers for PyPI
diff --git a/src/tm_devices/drivers/api/rest_api/rest_api_device.py b/src/tm_devices/drivers/api/rest_api/rest_api_device.py
index f3125f7d9..fc6609d82 100644
--- a/src/tm_devices/drivers/api/rest_api/rest_api_device.py
+++ b/src/tm_devices/drivers/api/rest_api/rest_api_device.py
@@ -140,7 +140,8 @@ def get(  # noqa: PLR0913
     def patch(  # noqa: PLR0913
         self,
         url: str,
-        json_body: Dict[str, Any],
+        json_body: Optional[Dict[str, Any]] = None,
+        data_body: Optional[str] = None,
         headers: Optional[Mapping[str, str]] = None,
         auth: Optional[Tuple[str, str]] = None,
         timeout: Optional[float] = None,
@@ -154,7 +155,11 @@ def patch(  # noqa: PLR0913
 
         Args:
             url: The url to PATCH.
-            json_body: Any data to send to the url.
+            json_body: Any data to serialize and send to the url.
+                The "Content-Type" header is set to "application/json".
+            data_body: Any raw data to send to the url. "Content-Type" must be set manually.
+                The data is not serialized. WARNING: IF DATA IS PASSED USING THIS ARGUMENT
+                THEN ANY DATA PASSED USING THE ``json_body`` ARGUMENT WILL BE IGNORED.
             headers: The headers to use during the request.
             auth: A tuple containing the username and password to use in the request.
             timeout: How many seconds to wait for the server to send data before giving up.
@@ -172,6 +177,7 @@ def patch(  # noqa: PLR0913
             SupportedRequestTypes.PATCH,
             url,
             json_body=json_body,
+            data_body=data_body,
             headers=headers,
             auth=auth,
             timeout=timeout,
@@ -187,6 +193,7 @@ def post(  # noqa: PLR0913
         self,
         url: str,
         json_body: Optional[Dict[str, Any]] = None,
+        data_body: Optional[str] = None,
         headers: Optional[Mapping[str, str]] = None,
         auth: Optional[Tuple[str, str]] = None,
         timeout: Optional[float] = None,
@@ -200,7 +207,11 @@ def post(  # noqa: PLR0913
 
         Args:
             url: The url to POST.
-            json_body: Any data to send to the url.
+            json_body: Any data to serialize and send to the url.
+                The "Content-Type" header is set to "application/json".
+            data_body: Any raw data to send to the url. "Content-Type" must be set manually.
+                The data is not serialized. WARNING: IF DATA IS PASSED USING THIS ARGUMENT
+                THEN ANY DATA PASSED USING THE ``json_body`` ARGUMENT WILL BE IGNORED.
             headers: The headers to use during the request.
             auth: A tuple containing the username and password to use in the request.
             timeout: How many seconds to wait for the server to send data before giving up.
@@ -218,6 +229,7 @@ def post(  # noqa: PLR0913
             SupportedRequestTypes.POST,
             url,
             json_body=json_body,
+            data_body=data_body,
             headers=headers,
             auth=auth,
             timeout=timeout,
@@ -232,7 +244,8 @@ def post(  # noqa: PLR0913
     def put(  # noqa: PLR0913
         self,
         url: str,
-        json_body: Dict[str, Any],
+        json_body: Optional[Dict[str, Any]] = None,
+        data_body: Optional[str] = None,
         headers: Optional[Mapping[str, str]] = None,
         auth: Optional[Tuple[str, str]] = None,
         timeout: Optional[float] = None,
@@ -246,7 +259,11 @@ def put(  # noqa: PLR0913
 
         Args:
             url: The url to PUT.
-            json_body: Any data to send to the url.
+            json_body: Any data to serialize and send to the url.
+                The "Content-Type" header is set to "application/json".
+            data_body: Any raw data to send to the url. "Content-Type" must be set manually.
+                The data is not serialized. WARNING: IF DATA IS PASSED USING THIS ARGUMENT
+                THEN ANY DATA PASSED USING THE ``json_body`` ARGUMENT WILL BE IGNORED.
             headers: The headers to use during the request.
             auth: A tuple containing the username and password to use in the request.
             timeout: How many seconds to wait for the server to send data before giving up.
@@ -264,6 +281,7 @@ def put(  # noqa: PLR0913
             SupportedRequestTypes.PUT,
             url,
             json_body=json_body,
+            data_body=data_body,
             headers=headers,
             auth=auth,
             timeout=timeout,
@@ -362,6 +380,7 @@ def _send_request(  # noqa: PLR0913,PLR0912,C901
         request_type: SupportedRequestTypes,
         url: str,
         json_body: Optional[Dict[str, Any]] = None,
+        data_body: Optional[str] = None,
         headers: Optional[Mapping[str, str]] = None,
         auth: Optional[Tuple[str, str]] = None,
         timeout: Optional[float] = None,
@@ -376,7 +395,11 @@ def _send_request(  # noqa: PLR0913,PLR0912,C901
         Args:
             request_type: The type of request to send.
             url: The url to use.
-            json_body: Any data to send to the url.
+            json_body: Any data to serialize and send to the url.
+                The "Content-Type" header is set to "application/json".
+            data_body: Any raw data to send to the url. "Content-Type" must be set manually.
+                The data is not serialized. WARNING: IF DATA IS PASSED USING THIS ARGUMENT
+                THEN ANY DATA PASSED USING THE ``json_body`` ARGUMENT WILL BE IGNORED.
             headers: The headers to use during the request.
             auth: A tuple containing the username and password to use in the request.
             timeout: How many seconds to wait for the server to send data before giving up.
@@ -435,6 +458,7 @@ def _send_request(  # noqa: PLR0913,PLR0912,C901
                     headers=headers,
                     auth=auth,
                     json=json_body,
+                    data=data_body,
                     timeout=timeout,
                     verify=verify_ssl,
                     allow_redirects=allow_redirects,
@@ -445,6 +469,7 @@ def _send_request(  # noqa: PLR0913,PLR0912,C901
                     headers=headers,
                     auth=auth,
                     json=json_body,
+                    data=data_body,
                     timeout=timeout,
                     verify=verify_ssl,
                     allow_redirects=allow_redirects,
@@ -455,6 +480,7 @@ def _send_request(  # noqa: PLR0913,PLR0912,C901
                     headers=headers,
                     auth=auth,
                     json=json_body,
+                    data=data_body,
                     timeout=timeout,
                     verify=verify_ssl,
                     allow_redirects=allow_redirects,