|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import sys |
|
import types |
|
from typing import Tuple, Union |
|
|
|
_REQUIRED_SYMBOLS = ("_protos", "_services", "_protos_and_services") |
|
_MINIMUM_VERSION = (3, 5, 0) |
|
|
|
_UNINSTALLED_TEMPLATE = "Install the grpcio-tools package (1.32.0+) to use the {} function." |
|
_VERSION_ERROR_TEMPLATE = "The {} function is only on available on Python 3.X interpreters." |
|
|
|
|
|
def _has_runtime_proto_symbols(mod: types.ModuleType) -> bool: |
|
return all(hasattr(mod, sym) for sym in _REQUIRED_SYMBOLS) |
|
|
|
|
|
def _is_grpc_tools_importable() -> bool: |
|
try: |
|
import grpc_tools |
|
return True |
|
except ImportError as e: |
|
|
|
|
|
if "grpc_tools" not in e.args[0]: |
|
raise |
|
return False |
|
|
|
|
|
def _call_with_lazy_import( |
|
fn_name: str, protobuf_path: str |
|
) -> Union[types.ModuleType, Tuple[types.ModuleType, types.ModuleType]]: |
|
"""Calls one of the three functions, lazily importing grpc_tools. |
|
|
|
Args: |
|
fn_name: The name of the function to import from grpc_tools.protoc. |
|
protobuf_path: The path to import. |
|
|
|
Returns: |
|
The appropriate module object. |
|
""" |
|
if sys.version_info < _MINIMUM_VERSION: |
|
raise NotImplementedError(_VERSION_ERROR_TEMPLATE.format(fn_name)) |
|
else: |
|
if not _is_grpc_tools_importable(): |
|
raise NotImplementedError(_UNINSTALLED_TEMPLATE.format(fn_name)) |
|
import grpc_tools.protoc |
|
if _has_runtime_proto_symbols(grpc_tools.protoc): |
|
fn = getattr(grpc_tools.protoc, '_' + fn_name) |
|
return fn(protobuf_path) |
|
else: |
|
raise NotImplementedError(_UNINSTALLED_TEMPLATE.format(fn_name)) |
|
|
|
|
|
def protos(protobuf_path): |
|
"""Returns a module generated by the indicated .proto file. |
|
|
|
THIS IS AN EXPERIMENTAL API. |
|
|
|
Use this function to retrieve classes corresponding to message |
|
definitions in the .proto file. |
|
|
|
To inspect the contents of the returned module, use the dir function. |
|
For example: |
|
|
|
``` |
|
protos = grpc.protos("foo.proto") |
|
print(dir(protos)) |
|
``` |
|
|
|
The returned module object corresponds to the _pb2.py file generated |
|
by protoc. The path is expected to be relative to an entry on sys.path |
|
and all transitive dependencies of the file should also be resolveable |
|
from an entry on sys.path. |
|
|
|
To completely disable the machinery behind this function, set the |
|
GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true". |
|
|
|
Args: |
|
protobuf_path: The path to the .proto file on the filesystem. This path |
|
must be resolveable from an entry on sys.path and so must all of its |
|
transitive dependencies. |
|
|
|
Returns: |
|
A module object corresponding to the message code for the indicated |
|
.proto file. Equivalent to a generated _pb2.py file. |
|
""" |
|
return _call_with_lazy_import("protos", protobuf_path) |
|
|
|
|
|
def services(protobuf_path): |
|
"""Returns a module generated by the indicated .proto file. |
|
|
|
THIS IS AN EXPERIMENTAL API. |
|
|
|
Use this function to retrieve classes and functions corresponding to |
|
service definitions in the .proto file, including both stub and servicer |
|
definitions. |
|
|
|
To inspect the contents of the returned module, use the dir function. |
|
For example: |
|
|
|
``` |
|
services = grpc.services("foo.proto") |
|
print(dir(services)) |
|
``` |
|
|
|
The returned module object corresponds to the _pb2_grpc.py file generated |
|
by protoc. The path is expected to be relative to an entry on sys.path |
|
and all transitive dependencies of the file should also be resolveable |
|
from an entry on sys.path. |
|
|
|
To completely disable the machinery behind this function, set the |
|
GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true". |
|
|
|
Args: |
|
protobuf_path: The path to the .proto file on the filesystem. This path |
|
must be resolveable from an entry on sys.path and so must all of its |
|
transitive dependencies. |
|
|
|
Returns: |
|
A module object corresponding to the stub/service code for the indicated |
|
.proto file. Equivalent to a generated _pb2_grpc.py file. |
|
""" |
|
return _call_with_lazy_import("services", protobuf_path) |
|
|
|
|
|
def protos_and_services(protobuf_path): |
|
"""Returns a 2-tuple of modules corresponding to protos and services. |
|
|
|
THIS IS AN EXPERIMENTAL API. |
|
|
|
The return value of this function is equivalent to a call to protos and a |
|
call to services. |
|
|
|
To completely disable the machinery behind this function, set the |
|
GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to "true". |
|
|
|
Args: |
|
protobuf_path: The path to the .proto file on the filesystem. This path |
|
must be resolveable from an entry on sys.path and so must all of its |
|
transitive dependencies. |
|
|
|
Returns: |
|
A 2-tuple of module objects corresponding to (protos(path), services(path)). |
|
""" |
|
return _call_with_lazy_import("protos_and_services", protobuf_path) |
|
|