if anyone is dealing with this in 2024, the 'official workaround' is to append the sys.path with the path of the .proto file parent directory, allowing the import statements in service_pb2_grpc.py to be processed properly.
Run the protoc command and create an __init__.py file under the parent directory of .proto file.
Here is a script that can be used to recursively process all .proto files under a specified directory, generating the protobuf files and creating necessary __init__.py to resolve import issues.
import os
import subprocess
from client import PROJECT_ROOT
proto_files_dir = os.path.join(PROJECT_ROOT, 'client', 'api')
for dirpath, dirnames, filenames in os.walk(proto_files_dir):
proto_files = [f for f in filenames if f.endswith('.proto')]
if proto_files:
# For each .proto file, run the protoc command to generate the Python files
for proto_file in proto_files:
print(f"Processing .proto file '{proto_file}'...", end=' ')
proto_file_path = os.path.join(dirpath, proto_file)
command = (
f'python3 -m grpc_tools.protoc '
f'--proto_path={dirpath} ' # Use proto_root_dir for --proto_path
f'--python_out={dirpath} '
f'--grpc_python_out={dirpath} '
f'{proto_file_path}'
)
subprocess.run(command, shell=True, check=True)
print("OK!")
# Create __init__.py in the directory of .proto file
init_file_path = os.path.join(dirpath, '__init__.py')
if not os.path.exists(init_file_path):
with open(init_file_path, 'w') as init_file:
init_file.write("import os\nimport sys\n\nsys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))\n")
print(f"Created __init__.py in {dirpath}")
See issue
protofolderpackage.proto.service_pb2from proto import ..., even ifprotodirectory will be inside another package, right?