Cannot convert proto.marshal.collections.maps.MapComposite to a Python dictionary
Determine this is the right repository
- [X] I determined this is the correct repository in which to report this bug.
Summary of the issue
According to a few answers on internet, I am expecting to use MessageToDict() to conver proto.marshal.collections.maps.MapComposite into a Python dictionary, but failed with
AttributeError: 'MapComposite' object has no attribute 'DESCRIPTOR'
API client name and version
altgraph 0.17.2 cachetools 5.3.3 certifi 2024.6.2 charset-normalizer 3.3.2 future 0.18.2 google-api-core 2.19.1 google-auth 2.30.0 google-cloud-access-context-manager 0.2.0 google-cloud-asset 3.26.1 google-cloud-iam 2.15.0 google-cloud-org-policy 1.11.0 google-cloud-os-config 1.17.3 googleapis-common-protos 1.63.2 grpc-google-iam-v1 0.13.1 grpcio 1.64.1 grpcio-status 1.62.2 idna 3.7 macholib 1.15.2 pip 24.1.1 proto-plus 1.24.0 protobuf 4.25.3 pyasn1 0.6.0 pyasn1_modules 0.4.0 requests 2.32.3 rsa 4.9 setuptools 58.0.4 six 1.15.0 urllib3 2.2.2 wheel 0.37.0
Reproduction steps: code
file: main.py
from google.cloud import asset_v1
from google.cloud import iam_admin_v1
from google.protobuf.json_format import MessageToDict
import re
# Initialize clients
asset_client = asset_v1.AssetServiceClient()
iam_client = iam_admin_v1.IAMClient()
# Set environment variables
FOLDER = "<folder-id>"
NAME = "monitoring"
def query_service_accounts(folder, name):
query = f"""
SELECT
[resource.data.name](http://resource.data.name/)
FROM
iam_googleapis_com_ServiceAccountKey
WHERE
[resource.data.name](http://resource.data.name/) LIKE "%/{name}%"
AND resource.data.keyType = "USER_MANAGED"
"""
response = asset_client.query_assets(
request={
"parent": f"folders/{folder}",
"statement": query,
"page_size": 500,
}
)
o = response.query_result.rows[0]
print ("FOO ", MessageToDict(o))
return [asset["name"] for asset in response.query_result.rows]
def describe_service_account(project, account_id):
service_account_name = f"projects/{project}/serviceAccounts/{account_id}"
return iam_client.get_service_account(name=service_account_name)
def main():
service_accounts = query_service_accounts(FOLDER, NAME)
print(service_accounts)
for service_account in service_accounts:
match = re.match(r'projects/([^/]+)/serviceAccounts/(.*)', service_account)
if match:
project, account_id = match.groups()
# Describe the service account
description = describe_service_account(project, account_id)
print(description)
if __name__ == "__main__":
main()
Reproduction steps: supporting files
None. The above script is self contained, but it depends on Application Default Credentials.
Reproduction steps: actual results
AttributeError: 'MapComposite' object has no attribute 'DESCRIPTOR'
Reproduction steps: expected results
Get a python disctionary
OS & version + platform
MacOS 14.5
Python environment
3.9.6
Python dependencies
Not sure
MessageToDict is part of the Protobuf API, however the library uses proto-plus which is a wrapper around the Protobuf API. For proto-plus objects, you can use the .to_dict() method of proto-plus to convert the proto-plus object to a dictionary. See the documentation of proto-plus for more information. If you're still having trouble, please provide the full stack trace to understand the issue better.
Note: There is an open issue in proto-plus related to a missing to_dict() method for MapComposite fields. If you run into this issue, please try the working which is dict(<object>) as mentioned in https://github.com/googleapis/proto-plus-python/issues/437.
I'm going to close this issue due to inactivity but please feel free to open a new issue with more information.