Skip to content

Importing well known types #9

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
Luminaar opened this issue Jan 6, 2020 · 11 comments
Open

Importing well known types #9

Luminaar opened this issue Jan 6, 2020 · 11 comments
Assignees
Labels
bug Something isn't working has test Has a (xfail) test that verifies the bugfix or feature medium priority medium Medium effort issue, can fit in a single PR

Comments

@Luminaar
Copy link
Contributor

Luminaar commented Jan 6, 2020

Hello,

I'm not sure how to work with well known types.

Having a proto file like this:

syntax = "proto3";      
      
package simple;      
      
import "google/protobuf/empty.proto";      
      
service SimpleSender {      
    rpc Send(SendParams) returns (google.protobuf.Empty) {}      
}      
      
message SendParams {      
    string body = 1;      
}

I get output like this:

# Generated by the protocol buffer compiler.  DO NOT EDIT!      
# sources: Simple.proto      
# plugin: python-betterproto      
from dataclasses import dataclass      
      
import betterproto      
import grpclib          
      
from .google import protobuf      
      
      
@dataclass      
class SendParams(betterproto.Message):      
    body: str = betterproto.string_field(1)      
      
      
class SimpleSenderStub(betterproto.ServiceStub):      
    async def send(self, *, body: str = "") -> protobuf.Empty:      
        request = SendParams()      
        request.body = body         
      
        return await self._unary_unary(      
            "/simple.SimpleSender/Send", request, protobuf.Empty,      
        )

There is ofcourse no google package. I tried to generate code from proto files included in grpc_tools but I'm not able to get any python code.

What is the best way to work with well known types?

@danielgtaylor danielgtaylor added the bug Something isn't working label Jan 10, 2020
@danielgtaylor
Copy link
Owner

It looks like the google.protobuf.Emtpy type is not currently supported. Someone will need to implement it in python-betterproto.

As a workaround you can define your own empty message until this is done.

@JoaoVasques
Copy link

Howdy people!

The same issue happens when I tried to use Struct.

from unbabelevents.chat_api import *
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-4950c13b1c3b> in <module>
----> 1 from unbabelevents.chat_api import *
~/chat_api.py in <module>
      9
     10 from . import commons
---> 11 from .google import protobuf
     12
     13

ModuleNotFoundError: No module named 'unbabelevents.google'

The proto file has the following message

syntax = "proto3";

import "google/protobuf/struct.proto";

message Nugget {
    repeated google.protobuf.Struct alerts = 1;
}

And the generated python class is

import betterproto

from . import commons
from .google import protobuf


@dataclass
class Nugget(betterproto.Message):
    qe_alerts: List[protobuf.Struct] = betterproto.message_field(1)

@devova
Copy link

devova commented Feb 26, 2020

It looks like the google.protobuf.Emtpy type is not currently supported. Someone will need to implement it in python-betterproto.

There is a google.protobuf.empty_pb2.Empty

@adisunw
Copy link

adisunw commented Feb 27, 2020

@devova yes but there are no generated dataclasses.

I made this module as a bandaid.

#  proto_types.py
from dataclasses import dataclass
import betterproto
from google.protobuf import struct_pb2



@dataclass
class Struct(betterproto.Message):
    def parse(self: betterproto.T, data: bytes) -> betterproto.T:
        decoded = struct_pb2.Struct.FromString(data)
        self.__dict__.update({item: value for item, value in decoded.items()})
        return self

    def __repr__(self):
        return repr(self.__dict__)


@dataclass
class Empty(betterproto.Message):
    def parse(self: betterproto.T, data: bytes) -> betterproto.T:
        return self

And then a post-generating find and replace.

with open(file_path, 'r') as f:
    lines = f.readlines()
with open(file_path, 'w') as f:
    for line in lines:
        line = line.replace("from .google import protobuf", "from wherever_proto_types_exists import proto_types")
        line = line.replace('protobuf.Empty', 'proto_types.Empty')
        line = line.replace('protobuf.Struct', 'proto_types.Struct')
        f.write(line)

where file_path is the path to the generated grpc python module

@boukeversteegh boukeversteegh self-assigned this May 25, 2020
@boukeversteegh boukeversteegh added the has test Has a (xfail) test that verifies the bugfix or feature label May 25, 2020
boukeversteegh added a commit to boukeversteegh/python-betterproto that referenced this issue May 25, 2020
@boukeversteegh boukeversteegh added this to the Better Imports milestone May 25, 2020
@boukeversteegh boukeversteegh added the medium Medium effort issue, can fit in a single PR label May 26, 2020
boukeversteegh added a commit to boukeversteegh/python-betterproto that referenced this issue May 28, 2020
boukeversteegh added a commit to boukeversteegh/python-betterproto that referenced this issue May 28, 2020
boukeversteegh added a commit to boukeversteegh/python-betterproto that referenced this issue May 28, 2020
boukeversteegh added a commit to boukeversteegh/python-betterproto that referenced this issue May 28, 2020
@boukeversteegh boukeversteegh linked a pull request May 28, 2020 that will close this issue
boukeversteegh added a commit to boukeversteegh/python-betterproto that referenced this issue May 29, 2020
@kalvdans
Copy link

Fixed by #78?

@kalzoo
Copy link
Collaborator

kalzoo commented Feb 11, 2021

Not Struct, unfortunately. If Struct is the only WKT used in your protobuf (as it is for me), you'll still have this dangling/invalid import. @adisunw 's patch fix at least unblocks the build, which is great.

Even easier than the find-replace that @adisunw provides above, if you just put that file in google/protobuf.py relative to the imported files you're in business.

@cetanu
Copy link
Collaborator

cetanu commented Mar 16, 2021

@lizelive
Copy link

lizelive commented Feb 3, 2022

I am also impacted by this issue.

@zbynekwinkler
Copy link

Is this still an issue? I am using wkt timestamp and it works for me with 2.0.0b5.

@krugi
Copy link

krugi commented Feb 15, 2023

Seems like it's still an issue. The lack of support for Empty, Value and FieldMask prevents me from using this (really nice!) library :(

@krugi
Copy link

krugi commented Feb 15, 2023

wait, seems like all of them are already here 🤔

class FieldMask(betterproto.Message):

Any idea why there's no files under from .google import protobuf? (generating using buf.build, if it matters)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working has test Has a (xfail) test that verifies the bugfix or feature medium priority medium Medium effort issue, can fit in a single PR
Projects
None yet
Development

Successfully merging a pull request may close this issue.