Web JSON to chop

Hello,

I am trying to convert posted json data with Web Server to chop where each property is a channel with their associated value.

I managed to transform the json into a table with this :

def onHTTPRequest(dat: webserverDAT, request: Dict[str, Any], 
				  response: Dict[str, Any]) -> Dict[str, Any]:
	"""
	Called when an HTTP request is received.
	
	Args:
		dat: The connected Web Server DAT
		request: Dictionary of request fields
		response: Dictionary defining the response to be filled in
		
	Returns:
		Dict[str, Any]: The response dictionary
	"""

	jsonVal = json.loads(request['data'].decode('utf-8'))
	print(jsonVal)

	op(dat).clear()
	for key, value in jsonVal.items():
		op(dat).appendRow((key,value))
#...

First issue here : I need to clear each time, does it mean that the value would be null during a brief period ?

With this I got a table but when using Dat to CHOP I can’t get my channels (see screenshot), what is the recommended way for this ?

Also since the project might start with no value how can I have a default value on each channel ?

Thanks for your help.

Welcome to the form @snchmt

Just to get you moving - you can change the parameter on your dattoCHOP to be Frist Row is Values and you should see a channel with the name of your first column, and a value from your second column:

You can use the dat from your webserver to hold your data, but IMO you’d be better served by writing this to another table. So you might make another table, and then use this other table as the store of your values from the sever.

Here below notice that there’s a newly added variable called data_store that’s a table, and in the callbacks we update this table.

data_store = op('table1')

def onHTTPRequest(dat: webserverDAT, request: Dict[str, Any], 
				  response: Dict[str, Any]) -> Dict[str, Any]:
	"""
	Called when an HTTP request is received.
	
	Args:
		dat: The connected Web Server DAT
		request: Dictionary of request fields
		response: Dictionary defining the response to be filled in
		
	Returns:
		Dict[str, Any]: The response dictionary
	"""

	jsonVal = json.loads(request['data'].decode('utf-8'))
	print(jsonVal)

	data_store.clear()
	for key, value in jsonVal.items():
		data_store.appendRow((key,value))
#...

You could clear your table each time, but to your question about defaults and starting values, you might instead update a row if it exists, and then add a row if you get a new key.

You can do that with a try and except block:

data_store = op('table1')

for key, value in jsonVal.items():
    try:
        data_store[key, 1] = value

    except Exception as e:
        data_store.appendRow([key, value])

The idea here is that your table could then hold start-up values that are only updated when you pull fresh data from the server.

Thanks ! It does solves all my issues.

I find it really confusing to use the “First row is” “values” while data is processed by row. Shouldn’t it be named First column ?

My understanding is that this is partially because data in CHOPs can be 2 dimensional - channels can hold an array of samples (values). So in this case:

Each row is a channel, the first column is names, and there are values in the row (except the 0th column).

There’s also a world where you might want to ignore the first row (e.g. if they where headers)

I agree that it’s initially confusing, but is very flexible for moving data into channels from tables once you get a feel for the op.

@snchmt I should also call out here that this is a JSON DAT - if you right click on the JSON data in your op create dialog and take a look at the Op Snippets

You should see that you can also create a table out of a json blob:

Another option would be to dump your data into a text DAT, then parse and format with a JSON DAT, and finally convert with a DAT to CHOP.