Return PythonShell output to a http response

Hi,

I'm somewhat new to NR, but have some python scripts that are triggered via HTTP POSTs to Node Red that are working great. However, I want to complete the transaction by returning the script output to the original http request, and I'm struggling.

It seems I need to get the msg.payload string and convert it to an object and render with a template and return it with a HTTP response, but I've been unsuccessful.

I am able to prove that I've created a msg object with the text of my script output, but the HTTP response continuously outputs to the debug window as "No Response Object"

I've added content-type headers and just want to return the formatted JSON.

Any thoughts?

1 Like

It might be easier to understand what you are doing if you can share your flow

1 Like

The issue will (probably) be that the python shell is creating a new msg object for its output. The http in and out nodes need the msg.res property to be maintained all the way through. Or it needs to be saved in context, and then rejoined with the python output before going to the http out.

2 Likes

I'm struggling with the same issue. When using PythonShell node with HTTP Response node, the output is always "No Response Object". How do we return a response object to the HTTP response node?
@lunawire if you get how to solve this then please respond.

Welcome to the forum @mrituanjayss

That node has not been updated in three years and there are unnadressed issues against it, which suggests that it is no longer supported by the author.
Looking at what it does I can't see any advantage over using an Exec node, so I suggest you switch to using that.

1 Like

Hi @Colin , Thanks for your reply. I think you're right. The command line arguments in pythonshell node is also ambiguous. On the other hand the Exec provides a way of giving command line arguments. Anyhow both of these nodes will be running a python script. The question is how does that python script give a response object to the HTTP response node? Let's say I have a function which returns an output which is wired to the HTTP response node and when I run the flow the output is still "No response object".

What are you doing in the python script?

A HTTP-response node MUST consume a message object that starts from a HTTP-in node.

The HTTP-in node attaches the response object to this message so it can be used by the HTTP-response node.

If any node in the flow creates a new msg object rather than just modifying the input node then this object will be lost and the HTTP-response node will fail.

It has simple database functions to read, update, delete, insert data from a database using sqlite3

Code in Py file:

import sqlite3
import json
import sys
con = sqlite3.connect('PCgamers.db')

c = con.cursor()

#c.execute("CREATE TABLE gamers (name text, game text, ytsubs integer)") 


def read():
	c.execute("SELECT * FROM gamers")
	listA = c.fetchall()
	return json.dumps(listA)
	

def insert(name, game, subs):
	c.execute("INSERT INTO gamers VALUES ('{}', '{}', {})".format(name, game, subs))	


def update(name, newname, newgame, newsubs):
	c.execute("UPDATE gamers SET name = '{}', game = '{}', ytsubs = {} where name = '{}'".format(newname, newgame, newsubs, name))


def delete(name):
	c.execute("DELETE from gamers where name = '{}'".format(name))

n = len(sys.argv)

def db_methods(n):
	if n == 2:
		return read()
	if n == 3:
		return delete(sys.argv[1])
	if n == 5:
		return insert(sys.argv[1], sys.argv[2], int(sys.argv[2]))
	if n == 6:
		return update(sys.argv[1], sys.argv[2], sys.argv[3], int(sys.argv[4]))
	
db_methods(n)

Where are you doing the http-in operation to which you want to respond?

Also, you could do the database operations in node-red, but that is a different issue.

Okay, shall I connect the HTTP Response node directly to the HTTP-in node ?

If that is the extent of the python, you might want to consider doing it all in node-red. Writing to a sqlite database is trivial. Then you avoid all the issues of spawning external process and parsing the response.

Having looked at the PythonShell node I do think it will ever work with the HTTP-in/HTTP-response nodes

Ever or never?

Ever.

To say "do not think it will never work" would be a double negative (and basically meaningless)

The HTTP node will send a POST request containing query parameters in it's URL(http://xyz/api/database?name=testgamer&game=testgame&subs=7000. Those query parameters will be then taken as command line arguments in PythonShell node. The python script will calculate the number of query parameters and decide which function needs to be run (Ex : 3-parameters mean an Insert func) . The script works and everything goes well but the output comes as "No reponse object"

As said this is expected behaviour with this node, the node is badly designed and has been pointed out not been updated in many years.

There are a number of solutions:

  1. stash the msg.res in the context before the python node and reattach it after. This can be done with 2 change nodes, but is a nasty hack with the possibility of race conditions.
  2. Use the exec node as has already been suggested
  3. scrap all the python and do it all in Node-RED using the sqlite nodes.

Option 3 is best way forward.

I think the first option is the one I never tried. The next two methods will work. The point is that I have been told to play with this PythonShell node and make it work. I'm gonna try the first one and respond. Thanks

Is this a class exercise? If so tell whoever is telling you to do it that it pointless as the node is dead.

It's a job training exercise and they have a full flow working with PythonShell node. The node is not dead, it is just not updated. Also a new issue now my Node-Red server is running but the browser can't open it. It says : This site can’t be reached