Webclient dat issue

Previously I was using requests library to query our server

import requests
url = "http://server:8080/query"
params = {"topic": "devices", "depth": -1, "flatten": True}
r = requests.post(url, json=params)
print(r.json())

Now I’m trying to use the webclient DAT

url = "http://server:8080/query"
header = {'Content-type': 'application/json'}
params = {"topic": "devices", "depth": -1, "flatten": True}
op("webclient1").request(url, "POST", header=header, data = params)

But I get

{“error”:400,“message”:“The request body must be a JSON object with a ‘topic’ and optional ‘depth’ property, or a JSON array of such objects.”}

any ideas where the error is ?

At first glance, I think your params dictionary should be a string.

but if I try this

params = '{"topic": "devices", "depth": -1, "flatten": True}'
op("webclient1").request(url, "POST", header=header, data = params)

or json.dumps(params)

I get this error

td.Error: Invalid number or type of arguments. See help for details. Value:(‘http://broker.backend.staging.t-gallery:8080/query’, ‘POST’) Type:<class ‘tuple’>.

Ahh, looks like it’s erroring because it expects a dictionary in the data keyword. However it’s valid in some cases to pass a string, so the python method is too restrictive. I’ll fix this.

The request pulse parameter won’t have these restrictions, so a workaround for the time being is to put the headers in a table DAT as the first input, and the json in a text DAT as the second input and just use the parameter to send request.

that works.thank you!

One additional question. When using async requests, is there a way (without changing our server code) to include some kind of ID in the POST, so I can identify it in the def onResponse() callback?

edit: and I just noticed that if I run this

op(“webclient2”).request(“https://www.google.com/search”, “GET”, header=None, data = None)
op(“webclient2”).request(“https://www.google.com/search”, “GET”, header=None, data = None)

I only get one response.

The Web Client DAT doesn’t support subsequent requests like this when in asynchronous mode. You’ll need to disable asynchronous mode, in which case the responses will arrive in the same order that they were requested.

Hey there Eric, I’m trying out some things with the webClient, particularly for testing remote control of Unreal via its Web Remote Control plugin ( https://docs.unrealengine.com/en-US/Engine/Editor/ScriptingAndAutomation/WebControl/index.html ).

I was wondering if the issue you and Achim found with regard to the request() method has been addressed in 24520 as I think I may be encountering similar issues. I can get the pulse/input workflow working, and I can get the same thing working by json.dumps() of my data blob using the request() method, but I can’t seem to just send the dictionary in for the data argument. Not a big deal i suppose, just an extra step, but sounded like you intended otherwise?

Thanks!
P

Yeah, I fixed the issue with the request method not accepting a string in the data keyword. Using the request method should work the same as the pulse/input DAT workflow so it sounds like there may be another issue.

Could you attach an example of what you’re trying to send?