Search code examples
google-cloud-platformgoogle-apigoogle-api-python-client

Google API python convert object to json


I'm new to google apis after spending the last 5 years dealing with Boto3 in AWS.

My problem is the following code snippet:

from google.cloud import resource_manager

def main():

    client = resource_manager.Client()

    # List all projects you have access to
    for project in client.list_projects():
        print(project['name'] + "" + project['status'])

if __name__ == '__main__':
    main()

However, for those in the know - you know that project is a Project object, not a dict. And therefore i cannot access it's children this way.

I tried to convert project using json.dumps(project) but it claims that it's not serializable. I toyed with flask and jsonify, but that's just too much overhead for a simple script to list projects and the status of them. This is one of many scripts i'll need to write. So i need to find a clean way to convert these types of objects to json format.

Here is what a Project object actually looks like:

project = {Project} <Project: 'remove label' ('sys-1234')>
 full_name = {str} 'projects/sys-1234'
 labels = {dict: 0} {}
 name = {str} 'remove label'
 number = {str} '571234'
 parent = {dict: 2} {'type': 'folder', 'id': '561234'}
 path = {str} '/projects/sys-1234'
 project_id = {str} 'sys-1234'
 status = {str} 'ACTIVE'

Can someone lend a hand? I've been spoiled with the very well written and easy to work with Boto libraries for the last few years. Struggling with this one.

Please advise, thank you.


Solution

  • Unless you manually craft some code, you cannot completely convert a class to json. Some classes have objects that are not serializable.

    The Resource Manager object has a dictionary property __dict__

    {
        '_client': <google.cloud.resource_manager.client.Client object at 0x000002A6391A89D0>,
        'project_id': 'mystic-advice-090909', 
        'name': 'Mystic Advice', 
        'number': '999999999999', 
        'labels': {}, 
        'status': 'ACTIVE', 
        'parent': None
    }
    

    You can get a close approximation by processing the dictionary:

    j = project.__dict__
    j2 = {}
    
    for k in j:
            if isinstance(j[k], str):
                    j2[k] = j[k]
    
    print(j2)
    

    Which results in:

    {
        'project_id': 'mystic-advice-090909', 
        'name': 'Mystic Advice', 
        'number': '999999999999', 
        'labels': {}, 
        'status': 'ACTIVE', 
        'parent': None
    }
    

    Note: my simple loop is not processing children that are themselves dictionaries. You would need to add additional code for those cases. Example if isinstance(j[k], dict):

    If you want to get creative, you can extend the Project class with a method to convert the object to JSON:

    def to_json(self):
            j = self.__dict__
            j2 = {}
    
            for k in j:
                    if isinstance(j[k], dict):
                            j2[k] = j[k]
                    if isinstance(j[k], str):
                            j2[k] = j[k]
            return j2
    
    resource_manager.project.Project.to_json = to_json
    
    client = resource_manager.Client()
    
    for project in client.list_projects():
            print(project.to_json())