Requests.post() vs. system.net.httpPost behavior

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:

payload = json.dumps(payload)

url = "https://ICantShowYouTheURL.com"

headerData = {"Content-Type" : "application/json"}

response = system.net.httpPost(url, headerData, payload) 
print(response)

Can someone shed some light on this? They're not logging the body on the receiving end so I can't tell what Ignition is actually sending.

thanks!

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']
3 Likes

From system.net.httpClient | Ignition User Manual

Exactly what @flexware said.

Also, if you do need to encode/decode json use

or

Always prefer Ignition first party java libraries, or standard java libraries, over jython libraries as a rule.

2 Likes

This worked. Thanks very much!

1 Like

Awesome, that's great to hear!

If you can, please mark this thread as answered so that we get that handy little icon next to the post title when browsing the forums.
image

[This helps people who are answering questions quickly see which posts need attention and which posts have been answered without clicking into them]

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.

thanks both of you for your help!

3 Likes

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.

1 Like

Sorry, I just saw your request.

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.

So you are saying that what you posted works, but

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")

is throwing an error?

Pssst!

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.

1 Like