Skip to content

Google Types - Any support #79

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

Open
boukeversteegh opened this issue May 30, 2020 · 7 comments
Open

Google Types - Any support #79

boukeversteegh opened this issue May 30, 2020 · 7 comments
Labels
enhancement New feature or request large Large effort issue, multiple PRs, needs to be split up low priority
Milestone

Comments

@boukeversteegh
Copy link
Collaborator

boukeversteegh commented May 30, 2020

Currently, betterproto does not understand Any messages, except that they have a url and bytes.

If you have suggestions for extended support, please be welcome to make them here.

@boukeversteegh boukeversteegh added the enhancement New feature or request label May 30, 2020
@boukeversteegh boukeversteegh changed the title Google Protobuf - Any support Google Types - Any support May 30, 2020
@boukeversteegh
Copy link
Collaborator Author

boukeversteegh commented May 30, 2020

@Evgenus - You requested support for Any

Thanks for this PR. I trapped into that issue a hour ago. Please add also import "google/protobuf/any.proto";

Originally posted by @Evgenus in #76 (comment)

Since I have no experience with Any, will simply importing it be enough? Or does it need special behavior when parsing an Any message?

We could generate the Any object with url and bytes or fully decode it on the fly. Any thoughts on this?

@boukeversteegh boukeversteegh added this to the Better Fields milestone Jun 8, 2020
@boukeversteegh boukeversteegh added large Large effort issue, multiple PRs, needs to be split up low priority labels Jul 12, 2020
@nhuray
Copy link

nhuray commented Jul 18, 2021

@boukeversteegh I saw you are involve in the some issues related to the support of Any type.

Do you know if there's some news for supporting Any in the coming releases ?

@boukeversteegh
Copy link
Collaborator Author

I'm not actively participating in betterproto anymore, but seeing that no new comments were added here, it looks like there are no concrete plans for implementing it.

The first step would be to define what Any support would look like. You're very welcome to share what could be a useful form of support for your use case.

@lizfeed
Copy link

lizfeed commented Sep 1, 2021

This is what I'm using right now. it doesn't play great with mypy (complains that it's not the google.lib.protobuf.Any) but otherwise it works for my JSON usecase:

@dataclass(eq=False, repr=False)
class Any(betterproto.Message):
    type_url: str = betterproto.string_field(1)
    value: betterproto.Message = betterproto.message_field(2)

    def to_dict(
        self, casing: betterproto.Casing = betterproto.Casing.CAMEL, include_default_values: bool = False
    ) -> Dict[str, Any]:
        raw_dict = super().to_dict(casing, include_default_values)
        dict_: Dict[str, Any] = {}
        type_url = casing('type_url').rstrip("_") # type: ignore
        if type_url in raw_dict:
            dict_['@type'] = raw_dict[type_url]
        value = casing('value').rstrip("_") # type: ignore
        dict_.update(raw_dict.get(value, {}))
        return dict_

@sunds
Copy link

sunds commented Sep 26, 2022

Still needed. I am using it to interface with Envoy, which uses Any.

Modified above code to work with python 3.10:

def to_dict(
    self, casing: betterproto.Casing = betterproto.Casing.SNAKE, include_default_values: bool = False
) -> Dict[str, object]:
    raw_dict = super().to_dict(casing, include_default_values)
    dict_: Dict[str, object] = {}
    type_url = casing('type_url').rstrip("_") # type: ignore
    if type_url in raw_dict:
        dict_['@type'] = raw_dict[type_url]
    value = casing('value').rstrip("_") # type: ignore
    dict_.update(raw_dict.get(value, {}))
    return dict_

@Galadrin
Copy link

here is my usecase :

I have the following proto message answer :

message QueryAccountsResponse {
  // accounts are the existing accounts
  repeated google.protobuf.Any accounts = 1 [(cosmos_proto.accepts_interface) = "cosmos.auth.v1beta1.AccountI"];

  // pagination defines the pagination in the response.
  cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

betterproto generate the folowing class:

@dataclass(eq=False, repr=False)
class QueryAccountResponse(betterproto.Message):
    """
    QueryAccountResponse is the response type for the Query/Account RPC method.
    """

    account: "betterproto_lib_google_protobuf.Any" = betterproto.message_field(1)
    """account defines the account of the corresponding address."""

When I request from a REST API, I'm getting the following answer :

 {'account': 
     {
       '@type': '/cosmos.auth.v1beta1.BaseAccount', 
       'account_number': '38', 
       'address': 'c4e1s3z7kvhtx8u7uruflz208phy5tuzhzlgv0h50k', 
       'pub_key': None, 
       'sequence': '0'
    }
}

I'm loading my Message with the following line :

QueryAccountResponse().from_dict(json.loads(json_response))

and get an empty object as result.

How can I have the ANY object ?

@iMaxGit
Copy link

iMaxGit commented Feb 2, 2024

@sunds I am also looking into using this for an Envoy interface, but I do not have much experience using betterproto. Would it be possible for you to share a short example, how you use the modified Any class in your code, please? Thank you

[Update]: I think I figured it out. I included the wrong "Any" class

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request large Large effort issue, multiple PRs, needs to be split up low priority
Projects
None yet
Development

No branches or pull requests

6 participants