Skip to content

Commit 11c8fc6

Browse files
authored
Smart text serialization (#12149)
* Smart text serialization * Update test_pipeline.py
1 parent 17d39be commit 11c8fc6

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

sdk/core/azure-core/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
- `AzureKeyCredentialPolicy` will now accept (and ignore) passed in kwargs #11963
99
- Better error messages if passed endpoint is incorrect #12106
10+
- Do not JSON encore a string if content type is "text" #12137
1011

1112
## 1.6.0 (2020-06-03)
1213

sdk/core/azure-core/azure/core/pipeline/transport/_base.py

+25
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,19 @@ def set_streamed_data_body(self, data):
319319
self.data = data
320320
self.files = None
321321

322+
def set_text_body(self, data):
323+
"""Set a text as body of the request.
324+
325+
:param data: A text to send as body.
326+
:type data: str
327+
"""
328+
if data is None:
329+
self.data = None
330+
else:
331+
self.data = data
332+
self.headers["Content-Length"] = str(len(self.data))
333+
self.files = None
334+
322335
def set_xml_body(self, data):
323336
"""Set an XML element tree as the body of the request.
324337
@@ -685,6 +698,11 @@ def _request(
685698
# type: (...) -> HttpRequest
686699
"""Create HttpRequest object.
687700
701+
If content is not None, guesses will be used to set the right body:
702+
- If content is an XML tree, will serialize as XML
703+
- If content-type starts by "text/", set the content as text
704+
- Else, try JSON serialization
705+
688706
:param str method: HTTP method (GET, HEAD, etc.)
689707
:param str url: URL for the request.
690708
:param dict params: URL query parameters.
@@ -703,8 +721,15 @@ def _request(
703721
request.headers.update(headers)
704722

705723
if content is not None:
724+
content_type = request.headers.get("Content-Type")
706725
if isinstance(content, ET.Element):
707726
request.set_xml_body(content)
727+
# https://github.com/Azure/azure-sdk-for-python/issues/12137
728+
# A string is valid JSON, make the difference between text
729+
# and a plain JSON string.
730+
# Content-Type is a good indicator of intent from user
731+
elif content_type and content_type.startswith("text/"):
732+
request.set_text_body(content)
708733
else:
709734
try:
710735
request.set_json_body(content)

sdk/core/azure-core/tests/test_pipeline.py

+19
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,25 @@ def test_request_url_with_params(self):
264264

265265
self.assertIn(request.url, ["a/b/c?g=h&t=y", "a/b/c?t=y&g=h"])
266266

267+
def test_request_text(self):
268+
client = PipelineClientBase('http://example.org')
269+
request = client.get(
270+
"/",
271+
content="foo"
272+
)
273+
274+
# In absence of information, everything is JSON (double quote added)
275+
assert request.data == json.dumps("foo")
276+
277+
request = client.post(
278+
"/",
279+
headers={'content-type': 'text/whatever'},
280+
content="foo"
281+
)
282+
283+
# We want a direct string
284+
assert request.data == "foo"
285+
267286

268287
if __name__ == "__main__":
269288
unittest.main()

0 commit comments

Comments
 (0)