I was hoping someone here could give me some advice on sending a json payload to a remote endpoint.
To get the json formatted and test things out more easily in a comfortable development environment, I've been using requests.post(payload) in my code to transfer the payload to the remote site. I've been successful there, 200 for a response. When I lift that code and replace the requests.post with system.net.httpPost(payload) I'm getting 415s back, unsupported media type. Since the payload is an identical string, I assume that the Ignition function behaves differently than requests. I'm pretty sure the problem is in the parameters I'm feeding httpPost since the same payload works with requests.post(). Here's the code in question:
That is strange... what if you try something like this instead (replacing .httpPost with .httpClient.post() and not encoding payload as a JSON string):
# Create the JythonHttpClient.
client = system.net.httpClient()
payload = payload # coming from your script above
url = "https://ICantShowYouTheURL.com"
# Send a POST request
### payload being a dict will automatically
### set the content type to `application/json`
response = client.post(url, data=payload)
# Validate the response.
if response.good:
# Do something with the response
print response.json['args']['a']
It turns out that it didn't quite do it. The documentation and bkarabinchak.psi above indicate that a dictionary would be automatically converted to JSON with the "data = my dictionary" parameter but it didn't didn't do that. The endpoint accepted the data but the system behind it rejected it as malformed.
I encoded it above the client.post() with system.util.jsonEncode (thanks bkarabinchak.psi!) and specified the content type, and I was back in business.
Interesting, can you show your code? I would imagine Ignition is doing a system.util.jsonEncode under the hood if it detects a dictionary, so I find it odd it only works if you manually encode it.
try:
sensorData = system.util.jsonEncode(sensorData)
url = "a URL I can't show you"
client = system.net.httpClient()
response = client.post(url, data = sensorData, headers = {"Content-Type":"application/json"})
print(response)
if response.good:
print("payload posted")
sensorData is a dictionary until the system.util.jsonEncode. Python reports that it's unicode after that. Specifying the Content-Type formatted it in an acceptable way for the remote system to process.
try:
sensorData = {'someKey':'somevalue'}
url = "a URL I can't show you"
client = system.net.httpClient()
response = client.post(url, data = sensorData, headers = {"Content-Type":"application/json"})
print(response)
if response.good:
print("payload posted")
Don't make a new instance of httpClient() with every operation. It is intended to be reused over many requests. Delegate to a project library script function, and place the client = system.net.httpClient() call outside the function.