From c16287063cd2d54a360c19e22b29a23da1d29a28 Mon Sep 17 00:00:00 2001 From: Egor Deev Date: Tue, 6 Oct 2026 00:38:57 +0000 Subject: [PATCH] =?UTF-8?q?gRPC:=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=81=D1=82=D0=BE=D1=8F=D1=89=D0=B8=D0=BC=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B5=D1=80=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Путь к сгенерированным модулям считался на уровень выше репозитория, импорт всегда падал, и вместо gRPC работала заглушка с поддельным success: true. Путь исправлен, заглушка убрана; адрес и таймаут — GRPC_SERVER и GRPC_TIMEOUT (пусто — шаг пропускается), недоступный сервер даёт success: false. proto/*_pb2*.py пересобраны под актуальный protobuf. --- api_app/grpc_client/client.py | 108 +++++++++------------------------ proto/text_service_pb2.py | 8 +-- proto/text_service_pb2_grpc.py | 10 +-- 3 files changed, 37 insertions(+), 89 deletions(-) diff --git a/api_app/grpc_client/client.py b/api_app/grpc_client/client.py index 2b1d7fe..a100e5e 100644 --- a/api_app/grpc_client/client.py +++ b/api_app/grpc_client/client.py @@ -1,90 +1,38 @@ -# api_project/api_app/grpc_client/client.py -import grpc +import logging import os import sys -# Добавляем путь для импорта сгенерированных протофайлов -current_dir = os.path.dirname(os.path.abspath(__file__)) -proto_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(current_dir))), 'proto') -sys.path.append(proto_dir) +import grpc +from django.conf import settings -# Пробуем импортировать сгенерированные протофайлы -# Если не получится, используем заглушки -try: - import text_service_pb2 - import text_service_pb2_grpc - print("Успешно импортированы сгенерированные proto файлы") -except ImportError: - print("Не удалось импортировать сгенерированные proto файлы, используем заглушки") - - # Создаем заглушки - class TextRequest: - def __init__(self, text): - self.text = text - - class TextResponse: - def __init__(self, processed_text, success, error): - self.processed_text = processed_text - self.success = success - self.error = error - - class TextProcessorStub: - def __init__(self, channel): - self.channel = channel - - def ProcessText(self, request): - # Эмулируем ответ от gRPC сервера - return TextResponse( - processed_text=f"ЗАГЛУШКА ОБРАБОТКИ ТЕКСТА: {request.text}", - success=True, - error="" - ) - - # Создаем модуль заглушки - class text_service_pb2: - TextRequest = TextRequest - TextResponse = TextResponse - - class text_service_pb2_grpc: - TextProcessorStub = TextProcessorStub +# сгенерированные модули лежат в proto/ в корне репозитория (раньше путь считался на уровень +# выше репозитория — импорт всегда падал, и вместо настоящего gRPC работала заглушка +# с поддельным success: true) +PROTO_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "proto") +if PROTO_DIR not in sys.path: + sys.path.append(PROTO_DIR) + +import text_service_pb2 # noqa: E402 +import text_service_pb2_grpc # noqa: E402 + +logger = logging.getLogger(__name__) + + +def send_to_grpc_server(text: str): + """Отправляет текст на gRPC-сервер TextProcessor. Если адрес сервера не задан + (GRPC_SERVER пустой), шаг пропускается и возвращается None""" + if not settings.GRPC_SERVER: + return None -def send_to_grpc_server(text: str) -> dict: - """ - Отправляет текст на gRPC сервер для обработки - - Args: - text: Текст для обработки - - Returns: - dict: Результат обработки - """ try: - # Создаем соединение с сервером - # Для заглушки это не обязательно, но оставим для совместимости - try: - channel = grpc.insecure_channel('localhost:50051') - except NameError: - # Если grpc не импортирован, используем заглушку - channel = "dummy_channel" - - # Создаем клиент - stub = text_service_pb2_grpc.TextProcessorStub(channel) - - # Создаем запрос - request = text_service_pb2.TextRequest(text=text) - - # Отправляем запрос - response = stub.ProcessText(request) - - # Возвращаем результат + with grpc.insecure_channel(settings.GRPC_SERVER) as channel: + stub = text_service_pb2_grpc.TextProcessorStub(channel) + response = stub.ProcessText(text_service_pb2.TextRequest(text=text), timeout=settings.GRPC_TIMEOUT) return { 'processed_text': response.processed_text, 'success': response.success, - 'error': response.error if hasattr(response, 'error') and response.error else None - } - except Exception as e: - return { - 'processed_text': None, - 'success': False, - 'error': str(e) + 'error': response.error or None, } + except grpc.RpcError as e: + logger.warning("gRPC-сервер %s недоступен: %s", settings.GRPC_SERVER, e.code()) + return {'processed_text': None, 'success': False, 'error': f"gRPC: {e.code().name}"} diff --git a/proto/text_service_pb2.py b/proto/text_service_pb2.py index 6311ce1..518a936 100644 --- a/proto/text_service_pb2.py +++ b/proto/text_service_pb2.py @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # NO CHECKED-IN PROTOBUF GENCODE # source: text_service.proto -# Protobuf Python Version: 5.29.0 +# Protobuf Python Version: 7.35.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -11,9 +11,9 @@ from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder _runtime_version.ValidateProtobufRuntimeVersion( _runtime_version.Domain.PUBLIC, - 5, - 29, - 0, + 7, + 35, + 1, '', 'text_service.proto' ) diff --git a/proto/text_service_pb2_grpc.py b/proto/text_service_pb2_grpc.py index 4f08cdc..3ab1f65 100644 --- a/proto/text_service_pb2_grpc.py +++ b/proto/text_service_pb2_grpc.py @@ -5,7 +5,7 @@ import warnings import text_service_pb2 as text__service__pb2 -GRPC_GENERATED_VERSION = '1.71.0' +GRPC_GENERATED_VERSION = '1.84.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -18,14 +18,14 @@ except ImportError: if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in text_service_pb2_grpc.py depends on' + + ' but the generated code in text_service_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' ) -class TextProcessorStub(object): +class TextProcessorStub: """Missing associated documentation comment in .proto file.""" def __init__(self, channel): @@ -41,7 +41,7 @@ class TextProcessorStub(object): _registered_method=True) -class TextProcessorServicer(object): +class TextProcessorServicer: """Missing associated documentation comment in .proto file.""" def ProcessText(self, request, context): @@ -66,7 +66,7 @@ def add_TextProcessorServicer_to_server(servicer, server): # This class is part of an EXPERIMENTAL API. -class TextProcessor(object): +class TextProcessor: """Missing associated documentation comment in .proto file.""" @staticmethod