0

I am using GCP's Python client APIs for listing cloud assets. I need to move that output to a CSV file. But I can't because it is showing

TypeError: Object of type Asset is not JSON serializable

My code

response = client.list_assets(
  request={
    "parent": project_resource,
    "read_time": None,
    "asset_types": ["compute.googleapis.com/Instance"],
    "content_type": asset_v1.ContentType.RESOURCE,
    "page_size": 50,
  }
)

for asset in response:
   print(asset)
df = json_normalize(asset)
df.to_csv('list.csv', sep=',', encoding='utf-8')`

My output

TypeError: Object of type Asset is not JSON serializable

Do I need to use any other library files to convert to CSV?

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
  • Could you please provide an example of the output of ```print(asset)``` – Sam Dec 16 '21 at 15:41
  • Here is my output of the old case (Note: i have highlighted like " ****** " are project name, project id....its sensitive name that's y i blurred. `name: "//compute.googleapis.com/projects/********/zones/us-central1-c/instances/*****" asset_type: "compute.googleapis.com/Instance" resource { version: "v1" discovery_document_uri: "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest" discovery_name: "Instance" parent: "//cloudresourcemanager.googleapis.com/projects/********" data { fields { key: "allocationAffinity" value { struct_value {......` – sudhar chrome Dec 17 '21 at 05:07

1 Answers1

1

I suspect Asset is a protocol buffer message and (these classes are) not JSON serializable.

NOTE Confirmed that Asset is a protocol buffer. The method uses gRPC Transcoding, see assets.list

You should (!) be able to use MessageToJSON in google.protobuf.json_format to convert the protobuf message into JSON that you can then convert to CSV. The module also includes MessageToDict which may (!?) be preferable in this case.

Update

Apparently (!) Google has changed its Protobuf support with API Client Libraries and uses Proto Plus for Python. I did not know this until your question. The solution is now (!):

for asset in resp:
    j = asset_v1.Asset.to_json(asset)

And, IIUC, because you need to to_json the protocol buffer messages, you will need to iterate over resp, to_json each (!?) asset and then reassemble them before converting to CSV.

NOTE Your code appears (!?) to create each Asset in the response as a separate CSV file (list.csv) when, I suspect you really want to serialize the response's assets property (list of Asset) instead.

DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • Hii @DazWilkin as u said `j = asset_v1.Asset.to_json(asset)` is working perfectly. now the thing is that for empty resoures it is not printing any result, not even empty string. For eg: `"asset_types": ['storage.googleapis.com/Bucket', 'container.googleapis.com/Cluster'],` Only for cluster it is printing, if there is no resourses in bucket, its not printing any thing not even "None",'empty'...... The problem is, i need to get intimated by printing "No resourse found" if there is nothing in bucket. How can I achive that can u help it out? – sudhar chrome Dec 21 '21 at 08:33
  • This is really a different question. The documentation for `assets.list`, the [Response](https://cloud.google.com/asset-inventory/docs/reference/rest/v1/assets/list#response-body) should (!) include `readTime`, `assets` and `nextPageToken`. The SDK doc explains that we really get a [`ListAssetsPager`]((https://googleapis.dev/python/cloudasset/latest/asset_v1/asset_service.html?highlight=list_assets#google.cloud.asset_v1.services.asset_service.pagers.ListAssetsPager)) pager from the method. – DazWilkin Dec 21 '21 at 17:37
  • It is a wrapper over [`ListAssetResponse`](https://googleapis.dev/python/cloudasset/latest/asset_v1/types.html#google.cloud.asset_v1.types.ListAssetsResponse) so you can actually `if len(resp.assets)==0 ...` – DazWilkin Dec 21 '21 at 17:37