Search code examples
pythonpython-3.xabstract-syntax-tree

ast.literal_eval() can't convert complex strings to lists in Python


I'm trying to iterate over all releases made in a repository in GitHub to find the latest release which is not draft nor prerelease also to find out the total release count.

I can get a list of all releases by the following code:

import requests
print(requests.get("https://api.github.com/repos/Yilmaz4/Encrypt-n-Decrypt/releases").text)

However, this returns a list that consists of multiple dictionaries (each of them represent a release) in a string format.

So I googled to convert string list to a list object and found this answer. When I tried it with the list that I received from the GET request I made above, I got an error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "c:\Users\ymzym\OneDrive\Python Projects\GitHub\Encrypt-n-Decrypt\main.pyw", line 731, in <lambda>
    self.fileMenu.add_command(label = "Check for updates", accelerator="Ctrl+Alt+U", command=lambda: self.Updates(self), underline=10)
  File "c:\Users\ymzym\OneDrive\Python Projects\GitHub\Encrypt-n-Decrypt\main.pyw", line 796, in __init__
    print(ast.literal_eval(get("https://api.github.com/repos/Yilmaz4/Encrypt-n-Decrypt/releases").text))
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 105, in literal_eval
    return _convert(node_or_string)
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 85, in _convert
    return list(map(_convert, node.elts))
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 94, in _convert
    return dict(zip(map(_convert, node.keys),
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 94, in _convert
    return dict(zip(map(_convert, node.keys),
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 104, in _convert
    return _convert_signed_num(node)
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 78, in _convert_signed_num
    return _convert_num(node)
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 69, in _convert_num
    _raise_malformed_node(node)
  File "C:\Users\ymzym\AppData\Local\Programs\Python\Python39\lib\ast.py", line 66, in _raise_malformed_node
    raise ValueError(f'malformed node or string: {node!r}')
ValueError: malformed node or string: <ast.Name object at 0x00000212D1EFF820>

According to the traceback, the library apparently thought that the string I provided was a dictionary.

How can I convert strings to lists no matter how complex the string is?


Solution

  • The server you are requesting the resource to replies with JSON data. You have to transform this JSON string to a Python data-structure. You could use the json module but fortunately, requests has a convenient function for this: .json():

    import requests
    
    response = requests.get("https://api.github.com/repos/Yilmaz4/Encrypt-n-Decrypt/releases")
    
    data = response.json()
    
    print(data)