Trouble passing a json object to a python file called by exec node

hello there, i know there have been other threads depicting similar errors, however, perhaps i have something going on wrong that i cant quite understand:
here is the main function of my python code:

if __name__ == "__main__":
    try:
        # Read input from Node-RED (via stdin)
        input_data = json.loads(sys.stdin.read())
        
        audio_path = input_data.get('audio_path')
        
        # Initialize detector with provided threshold or default value (0.5)
        detector = RPWDetector(threshold=input_data.get('threshold', 0.5))
        
        # Process audio file
        if audio_path:
            # Resolve relative paths if needed
            if not os.path.isabs(audio_path):
                script_dir = os.path.dirname(os.path.abspath(__file__))
                audio_path = os.path.join(script_dir, audio_path)
                
            # Check if file exists
            if not os.path.exists(audio_path):
                print(json.dumps({
                    'status': 'error',
                    'message': f'Audio file not found: {audio_path}'
                }))
                sys.exit(1)  # Return non-zero exit code for error
                
            result = detector.predict_class(audio_path)
            
            if result['status'] == 'success':
                # Output classification and probability in required format for Node-RED stdout
                print(json.dumps({
                    'classification': result['classification'],
                    'probability': result['probability']
                }))
                sys.exit(0)  # Return zero exit code for success
            
            else:
                print(json.dumps(result))
                sys.exit(1)  # Return non-zero exit code for error
                
        else:
            print(json.dumps({
                'status': 'error',
                'message': 'No audio path provided'
            }))
            sys.exit(1)  # Return non-zero exit code for error
            
    except Exception as e:
        print(json.dumps({
            'status': 'error',
            'message': str(e)
        }))
        sys.exit(1)  # Return non-zero exit code for error

image
my inject node


and my exec node calling the file.

now, when i pass this, nothing happens. it just shows a pid with a random number that changes every time i inject and nothing happens.

what ive tried:
using the json node to convert to string
putting "echo $payload | predict.py" and appending so it replaces the payload.

infact, directly inputting echo {"audio_path": "clean_1.wav"} | python predict.py
in the exec node works and i do get an output on stdout.

but i cant for the life of me manage to input it from outside the function

Since you appending the msg.payload (at the end of the command) that should be used as an argument ?
.. have you tried using sys.argv instead of sys.stdin.read()

input_data = json.loads(sys.argv[1])

yes, i appended it so it can be passed along to the file and read by

input_data = json.loads(sys.stdin.read())
        
        audio_path = input_data.get('audio_path')

to answer your question, i have tried using sys.argv. it returns this error:

attempts to solve this particular one... have been futile as well

Why are you passing a json object to Python rather than a simple string?

Does it work if you drop the json.loads and just pass clean_1.wav ?

What operating system are you using - is there an option to make predict.py executable and execute it (using the full pathname) rather than python?

I did some further tests and ..
i didnt manage to get it to work with sys.stdin.read()

But with sys.argv[1] :

If your msg.payload is an Object, when you Append it, what is actually sent is this :
Command failed: python c:\Users\user\.node-red\python_test.py [object Object]

and when we try to json parse the sys.argv[1] we get an error
{"status": "error", "message": "Expecting value: line 1 column 2 (char 1)"}

If you send the payload as a String
image
Again you will have a problem because the double quotes get stripped for some reason .. this can be verified by doing a print(sys.argv[1]) in python code. Results to {audio_path:clean_1.wav}
with missing double quotes and json.loads will fail again.

Your best chance is @jbudd 's recommendation to not sent the arguments as object
or escape the double quotes in the string {\"audio_path\":\"clean_1.wav\"}

thank you both. it did indeed work when i changed

        
        audio_path = input_data.get('audio_path')

to

 audio_path = sys.stdin.read()

i passed the input from the inject node as a string instead of json object, "clean_1.wav" without the quotes

however, a slightly confusing thing happens... it sometimes works, and it sometimes doesnt but doesnt output an error or anything.

i put a debug node on stdout, stderr, and return code and.... nothing happens. it just keeps being like this forever
image

however, sometimes it runs and outputs in a few seconds and even after trying again, it outputs correctly and everything

what could be the cause of this confusion?

i know for sure it isnt coming from the file itself, because when i change the audio_path directly to clean_1.wav instead of reading input, it outputs correctly and everything, so the problem must be from node-red itself

EDIT:

for any future people who might run into this problem, the pythonshell custom node fixed this problem. nothing was changed except that instead of the exec node calling the file by python filename.py, i added pythonshell and configured it to run the file as is.i will edit this post if any new errors come up.

I don't think you can safely conclude that.

Good to discover there are occasions when that node resolves problems.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.