[Python-es] Dichoso GRPC en Python

Miguel de Dios Matias tres.14159 en gmail.com
Sab Mar 19 11:21:49 EDT 2022


Buenas.

Me estoy haciendo unos POC en python sobre GRPC porque un compa del
curro lo quiere meter.

Y ya casi tengo (después de mucho sufrimiento...me da que no tiene
muchs comunidad y esta medio abandonado GRPC salvo en Golang) todos
los posibles formas de comunicación.

Pero me queda la que el request sea un stream, bueno a medias, porque
sincrona (que se quede clavado el client.py enviando mensajes si) pero
asyncrona, naranjas de la china.

Mi último intento fallido es:

test.proto
---------------------------------------------------------
syntax = "proto3";

message Saludo {
  string nombre = 1;
  int32  segundo = 2;
}
message Respuesta {
  string frase = 1;
  int32 segundo = 2;
}
service Saluda {
  // Sends a greeting
  rpc buenosdias (stream Saludo) returns (stream Respuesta) {}
}
-----------------------------------------------------

client.py
-------------------------------------------------------
import grpc
from concurrent import futures

# Generate pb2 and bp2_grpc generated python files
# python3 -m grpc_tools.protoc --proto_path=. --python_out=.
--grpc_python_out=. ./*.proto

import test_service_pb2_grpc
import test_pb2

from datetime import datetime
from time import sleep

import asyncio
from uuid import uuid4

class MyIterator:
    def __init__(self, start=0):
        self.num = start

    def __iter__(self):
        return self

    def __next__(self):
        sleep(2)
        nombre = uuid4()
        print(nombre)
        return test_pb2.Saludo(nombre=f'{nombre}',
segundo=datetime.now().second)


class AsyncIterator:
    def __aiter__(self):
        return self

    async def __anext__(self):
        await asyncio.sleep(2)
        nombre = uuid4()
        print(nombre)
        return test_pb2.Saludo(nombre=f'{nombre}',
segundo=datetime.now().second)


if __name__ == '__main__':
    print("TEST CLIENT GRPC")

    server_uri = 'localhost:50053'
    print(f"CONNECT TO: {server_uri}")
    with grpc.insecure_channel(server_uri) as channel:
        stub = test_service_pb2_grpc.SaludaStub(channel)
        # ~ saludo = test_pb2.Saludo(nombre=f'{uuid4()}',
segundo=datetime.now().second)
        # ~ stream_connection = stub.buenosdias(iter((saludo,saludo)))
        stream_connection = stub.buenosdias(MyIterator())
        for response in stream_connection:
            response_dict = {k.name: getattr(response, k.name) for k
in response.DESCRIPTOR.fields}
            print(f"CLIENTE RECEIVED: {response_dict}")
--------------------------------------------------------------------------------------

Con un iterador "sincrono" funciona pero se queda o llamando con un
iterador de 1 elemento puest también y solo se clava 1 vez pero si
meto:
stream_connection = stub.buenosdias(AsyncIterator())

Falla.

Saludos.


Más información sobre la lista de distribución Python-es