27

Why do I get this error message: ValueError: malformed node or string when I pass data in the below format into the "parse_webhook" function?

Thanks!

webhook_data = {"side": "BUY","key": "8234023409fa3242309sdfasdf903024917325"} def parse_webhook(webhook_data): """ :param webhook_data: POST data from tradingview, as a string. :return: Dictionary version of string. """ data = ast.literal_eval(webhook_data) return data 

Wrror I get:

 File "C:\Users\User\anaconda3\lib\ast.py", line 55, in _convert_num raise ValueError('malformed node or string: ' + repr(node)) ValueError: malformed node or string: {'side': 'BUY', 'key': '8234023409fa3242309sdfasdf903024917325'} 
5
  • 1
    What are you trying to do ? ast.literal_eval takes a string and return the python evaluated object, here you alreart have the object which is a dict. It would work for the string '{"side": "BUY","key": "8234023409fa3242309sdfasdf903024917325"}' Commented Jun 19, 2020 at 21:34
  • See my answer to a similar question: stackoverflow.com/questions/15197673/… Commented Aug 10, 2021 at 19:39
  • 5
    in my case, I was already passing a string. Problem was the string had some nulls in it. Fixed by ast.literal_eval(my_str.replace("null", "None")) Commented Dec 15, 2021 at 14:36
  • If you have null in the object, that’s probably JSON, and you should use json.loads instead of ast.literal_eval. Commented Oct 11, 2024 at 3:42
  • In particular, replacing null with None is how “John Snully” turns into “John SNoney”. Commented Oct 11, 2024 at 3:43

3 Answers 3

25

ast.literal_eval:

Safely evaluate an expression node or a Unicode or Latin-1 encoded string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

You cannot pass a dictionary to ast.literal_eval. It only takes a string input and converts it into appropriate python object. You can't pass lists / dictionary / tuples, etc to the ast.literal_eval .


Use Case:

The following snippet would have been a valid use of this method

import ast # Converting a string representation of dictionary into dictionary. webhook_data = ast.literal_eval('{"side": "BUY","key": "8234023409fa3242309sdfasdf903024917325"}') print(webhook_data) 

Output:

{'side': 'BUY', 'key': '8234023409fa3242309sdfasdf903024917325'} 

You could also use it when you have a list, tuple, booleans, numbers, sets etc in form of string and this method would evaluate it into appropriate python object.


Possible Fix to Error:

You already have a dictionary constructed with you. You could make your code work by doing the following edit:

webhook_data = {"side": "BUY","key": "8234023409fa3242309sdfasdf903024917325"} def parse_webhook(webhook_data): """ :param webhook_data: POST data from tradingview, as a string. :return: Dictionary version of string. """ data = ast.literal_eval(str(webhook_data)) return data 

But the above code would just be redundant. You are just converting a dictionary to string using str() and that converted string back into dictionary using a ast.literal_eval.


Notes:

  1. It is possible to crash the Python interpreter with a sufficiently large/complex string due to stack depth limitations in Python’s AST compiler.

  2. ast.literal_eval raises an exception if the input isn't a valid Python datatype, so the code won't be executed if it's not.

Sign up to request clarification or add additional context in comments.

Comments

7

ast.literal_eval() expects a string. Convert webhook_data to string with str() and it will work.

webhook_data = {"side": "BUY","key": "8234023409fa3242309sdfasdf903024917325"} def parse_webhook(webhook_data): """ :param webhook_data: POST data from tradingview, as a string. :return: Dictionary version of string. """ data = ast.literal_eval(str(webhook_data)) # this fixes the issue return data 

print(parse_webhook(webhook_data)) 

Output:

{'side': 'BUY', 'key': '8234023409fa3242309sdfasdf903024917325'} 

1 Comment

This does not work.
1

If the above solutions don't work for you, try using json.loads instead of ast.literal_eval, example:

 import json webhook_data = {"side": "BUY","key": "8234023409fa3242309sdfasdf903024917325"} content = json.loads(webhook_data) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.