mirror of
https://github.com/EDeev/api_processor.git
synced 2026-10-07 20:49:34 +03:00
gRPC: клиент работает с настоящим сервером
Путь к сгенерированным модулям считался на уровень выше репозитория, импорт всегда падал, и вместо gRPC работала заглушка с поддельным success: true. Путь исправлен, заглушка убрана; адрес и таймаут — GRPC_SERVER и GRPC_TIMEOUT (пусто — шаг пропускается), недоступный сервер даёт success: false. proto/*_pb2*.py пересобраны под актуальный protobuf.
This commit is contained in:
parent
fc2f750cee
commit
c16287063c
3 changed files with 37 additions and 89 deletions
|
|
@ -1,90 +1,38 @@
|
||||||
# api_project/api_app/grpc_client/client.py
|
import logging
|
||||||
import grpc
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Добавляем путь для импорта сгенерированных протофайлов
|
import grpc
|
||||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
from django.conf import settings
|
||||||
proto_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(current_dir))), 'proto')
|
|
||||||
sys.path.append(proto_dir)
|
|
||||||
|
|
||||||
# Пробуем импортировать сгенерированные протофайлы
|
# сгенерированные модули лежат в proto/ в корне репозитория (раньше путь считался на уровень
|
||||||
# Если не получится, используем заглушки
|
# выше репозитория — импорт всегда падал, и вместо настоящего gRPC работала заглушка
|
||||||
try:
|
# с поддельным success: true)
|
||||||
import text_service_pb2
|
PROTO_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "proto")
|
||||||
import text_service_pb2_grpc
|
if PROTO_DIR not in sys.path:
|
||||||
print("Успешно импортированы сгенерированные proto файлы")
|
sys.path.append(PROTO_DIR)
|
||||||
except ImportError:
|
|
||||||
print("Не удалось импортировать сгенерированные proto файлы, используем заглушки")
|
import text_service_pb2 # noqa: E402
|
||||||
|
import text_service_pb2_grpc # noqa: E402
|
||||||
# Создаем заглушки
|
|
||||||
class TextRequest:
|
logger = logging.getLogger(__name__)
|
||||||
def __init__(self, text):
|
|
||||||
self.text = text
|
|
||||||
|
def send_to_grpc_server(text: str):
|
||||||
class TextResponse:
|
"""Отправляет текст на gRPC-сервер TextProcessor. Если адрес сервера не задан
|
||||||
def __init__(self, processed_text, success, error):
|
(GRPC_SERVER пустой), шаг пропускается и возвращается None"""
|
||||||
self.processed_text = processed_text
|
if not settings.GRPC_SERVER:
|
||||||
self.success = success
|
return None
|
||||||
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
|
|
||||||
|
|
||||||
def send_to_grpc_server(text: str) -> dict:
|
|
||||||
"""
|
|
||||||
Отправляет текст на gRPC сервер для обработки
|
|
||||||
|
|
||||||
Args:
|
|
||||||
text: Текст для обработки
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Результат обработки
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
# Создаем соединение с сервером
|
with grpc.insecure_channel(settings.GRPC_SERVER) as channel:
|
||||||
# Для заглушки это не обязательно, но оставим для совместимости
|
stub = text_service_pb2_grpc.TextProcessorStub(channel)
|
||||||
try:
|
response = stub.ProcessText(text_service_pb2.TextRequest(text=text), timeout=settings.GRPC_TIMEOUT)
|
||||||
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)
|
|
||||||
|
|
||||||
# Возвращаем результат
|
|
||||||
return {
|
return {
|
||||||
'processed_text': response.processed_text,
|
'processed_text': response.processed_text,
|
||||||
'success': response.success,
|
'success': response.success,
|
||||||
'error': response.error if hasattr(response, 'error') and response.error else None
|
'error': response.error or None,
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
return {
|
|
||||||
'processed_text': None,
|
|
||||||
'success': False,
|
|
||||||
'error': str(e)
|
|
||||||
}
|
}
|
||||||
|
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}"}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||||
# NO CHECKED-IN PROTOBUF GENCODE
|
# NO CHECKED-IN PROTOBUF GENCODE
|
||||||
# source: text_service.proto
|
# source: text_service.proto
|
||||||
# Protobuf Python Version: 5.29.0
|
# Protobuf Python Version: 7.35.1
|
||||||
"""Generated protocol buffer code."""
|
"""Generated protocol buffer code."""
|
||||||
from google.protobuf import descriptor as _descriptor
|
from google.protobuf import descriptor as _descriptor
|
||||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
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
|
from google.protobuf.internal import builder as _builder
|
||||||
_runtime_version.ValidateProtobufRuntimeVersion(
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
||||||
_runtime_version.Domain.PUBLIC,
|
_runtime_version.Domain.PUBLIC,
|
||||||
5,
|
7,
|
||||||
29,
|
35,
|
||||||
0,
|
1,
|
||||||
'',
|
'',
|
||||||
'text_service.proto'
|
'text_service.proto'
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import warnings
|
||||||
|
|
||||||
import text_service_pb2 as text__service__pb2
|
import text_service_pb2 as text__service__pb2
|
||||||
|
|
||||||
GRPC_GENERATED_VERSION = '1.71.0'
|
GRPC_GENERATED_VERSION = '1.84.0'
|
||||||
GRPC_VERSION = grpc.__version__
|
GRPC_VERSION = grpc.__version__
|
||||||
_version_not_supported = False
|
_version_not_supported = False
|
||||||
|
|
||||||
|
|
@ -18,14 +18,14 @@ except ImportError:
|
||||||
if _version_not_supported:
|
if _version_not_supported:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f'The grpc package installed is at version {GRPC_VERSION},'
|
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' grpcio>={GRPC_GENERATED_VERSION}.'
|
||||||
+ f' Please upgrade your grpc module to 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}.'
|
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TextProcessorStub(object):
|
class TextProcessorStub:
|
||||||
"""Missing associated documentation comment in .proto file."""
|
"""Missing associated documentation comment in .proto file."""
|
||||||
|
|
||||||
def __init__(self, channel):
|
def __init__(self, channel):
|
||||||
|
|
@ -41,7 +41,7 @@ class TextProcessorStub(object):
|
||||||
_registered_method=True)
|
_registered_method=True)
|
||||||
|
|
||||||
|
|
||||||
class TextProcessorServicer(object):
|
class TextProcessorServicer:
|
||||||
"""Missing associated documentation comment in .proto file."""
|
"""Missing associated documentation comment in .proto file."""
|
||||||
|
|
||||||
def ProcessText(self, request, context):
|
def ProcessText(self, request, context):
|
||||||
|
|
@ -66,7 +66,7 @@ def add_TextProcessorServicer_to_server(servicer, server):
|
||||||
|
|
||||||
|
|
||||||
# This class is part of an EXPERIMENTAL API.
|
# This class is part of an EXPERIMENTAL API.
|
||||||
class TextProcessor(object):
|
class TextProcessor:
|
||||||
"""Missing associated documentation comment in .proto file."""
|
"""Missing associated documentation comment in .proto file."""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue