Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking Changes in version 10.0.0 #400

Closed
BenRKarl opened this issue Mar 31, 2021 · 5 comments
Closed

Breaking Changes in version 10.0.0 #400

BenRKarl opened this issue Mar 31, 2021 · 5 comments
Assignees

Comments

@BenRKarl
Copy link
Contributor

Version 10.0.0 of this library introduces a number of interface improvements that are not backwards compatible. For details please see our migration guide.

@Rukeith
Copy link

Rukeith commented Apr 23, 2021

How could I convert Object to JSON?
At 9.0.0, I still could use from google.protobuf.json_format import MessageToJson to convert response to json.
But at 10.0.0, I got the error

[2021-04-23 03:26:04,164] INFO in flasky: Body: {'code': 300, 'description': "'DESCRIPTOR'", 'message': 'API process failed', 'request': {'body': {'customers': ['5909684848'], 'end_date': '2021-04-21', 'start_date': '2021-03-03'}, 'url': 'http://localhost:5000/gads/activity_history'}, 'status': 'error', 'traceback': 'Traceback (most recent call last):\n  File "/usr/local/lib/python3.8/site-packages/proto/message.py", line 600, in __getattr__\n    pb_type = self._meta.fields[key].pb_type\nKeyError: \'DESCRIPTOR\'\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request\n    rv = self.dispatch_request()\n  File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request\n    return self.view_functions[rule.endpoint](**req.view_args)\n  File "./loupe/formatter.py", line 355, in wrapper\n    res = fn(*args, **kwargs)\n  File "/usr/local/lib/python3.8/site-packages/flask_jwt_extended/view_decorators.py", line 116, in decorator\n    return fn(*args, **kwargs)\n  File "./loupe/routes/google_ads.py", line 246, in get_activity_history\n    result = change_status_service.get_history_by_accounts(customers)\n  File "./loupe/google_ads/account.py", line 434, in get_history_by_accounts\n    data = gads_list_to_dict(response)\n  File "./loupe/formatter.py", line 321, in gads_list_to_dict\n    return [format_gads_to_dict(row) for row in list(rows)]\n  File "./loupe/formatter.py", line 321, in <listcomp>\n    return [format_gads_to_dict(row) for row in list(rows)]\n  File "./loupe/formatter.py", line 326, in format_gads_to_dict\n    return json.loads(MessageToJson(row, including_default_value_fields=True))\n  File "/usr/local/lib/python3.8/site-packages/google/protobuf/json_format.py", line 137, in MessageToJson\n    return printer.ToJsonString(message, indent, sort_keys)\n  File "/usr/local/lib/python3.8/site-packages/google/protobuf/json_format.py", line 204, in ToJsonString\n    js = self._MessageToJsonObject(message)\n  File "/usr/local/lib/python3.8/site-packages/google/protobuf/json_format.py", line 209, in _MessageToJsonObject\n    message_descriptor = message.DESCRIPTOR\n  File "/usr/local/lib/python3.8/site-packages/proto/message.py", line 605, in __getattr__\n    raise AttributeError(str(ex))\nAttributeError: \'DESCRIPTOR\'\n'}

@BenRKarl
Copy link
Contributor Author

Hi @Rukeith - that functionality exists on the constructor class for each message, you can access it like this:

campaign = client.get_type("Campaign")
json = type(campaign).to_json(campaign)
campaign = type(campaign).from_json(json)

@BenRKarl BenRKarl unpinned this issue Apr 26, 2021
@Rukeith
Copy link

Rukeith commented May 12, 2021

@BenRKarl
Hi, I have tried this. But I could fully understand.
I don't know how to fit this issue to format the google ads object to json.

ga_service = client.get_service("GoogleAdsService")
campaign = client.get_type("Campaign")

query = """
    SELECT
      campaign.id,
      campaign.name
    FROM campaign
    ORDER BY campaign.id"""

# Issues a search request using streaming.
response = ga_service.search_stream(customer_id=customer_id, query=query)

for batch in response:
    for row in batch.results:
       // Here is the solution
        json = type(campaign).to_json(campaign) ???
        campaign = type(row).from_json(json)
        print(json)
        print(campaign)

@totalhack
Copy link

totalhack commented Aug 31, 2021

Asking here since others finding this question may also run into the same issue and it's not stated above or in your docs that I can find...

Is there an equivalent to MessageToDict's preserving_proto_field_name option with the new proto_plus stuff? I used to do this:

dict_row = MessageToDict(row, preserving_proto_field_name=True)

But with the following the resulting format is different (camel case instead of snake case at a minimum, unclear if anything else changed yet as I'm just starting this wonderful journey):

dict_row = json.loads(type(row).to_json(row))

Thanks.

EDIT: after finding a discussion that points to this change I found the to_dict method. But note that to_dict returns snake case while to_json returns camel case. So this gives me the same as my original approach:

dict_row = type(row).to_dict(row)

@BenRKarl
Copy link
Contributor Author

@totalhack you can always access the corresponding protobuf message on a proto-plus message, so you can continue to use MessageToDict if that's the best option for you:

dict_row = MessageToDict(type(row).pb(row), preserving_proto_field_name=True)

That should give you the desired result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants