vmagamedov / grpclib

Pure-Python gRPC implementation for asyncio
http://grpclib.readthedocs.io
BSD 3-Clause "New" or "Revised" License
936 stars 92 forks source link

How to create a channel from URL #164

Open CaptTwigg opened 2 years ago

CaptTwigg commented 2 years ago

How do I create a channel where the host is an URL? eg: Channel(host="localhost/backendDev", port=5000)

The server is made in c# and runs in an windows service and the LaunchSettings look like this:

{
  "profiles": {
    "BackendLocalGrpc": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": false,
      "applicationUrl": "http://localhost:5000",
      "launchUrl": "backendDev",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Running it with just localhost works fine, but I use backend to distinguish between prod, test and dev environments.

vmagamedov commented 2 years ago

I don't know any gRPC server or client implementation which supports serving requests with some path prefix.

https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md

Some gRPC implementations may allow the Path format shown above to be overridden, but this functionality is strongly discouraged. gRPC does not go out of its way to break users that are using this kind of override, but we do not actively support it, and some functionality (e.g., service config support) will not work when the path is not of the form shown above.

I think that it is better to find another way to distinguish environments.

Is this server written by you or by someone else?

CaptTwigg commented 2 years ago

Have it in c#, but after a little testing it seem not to do anything, I will get back when I know more.

var channelOptionsLocal = new GrpcChannelOptions { MaxReceiveMessageSize = null };   // Remove MaxMessageSize limit
LocalManagerChannel = GrpcChannel.ForAddress(@"http://localhost:5000/backendDev", channelOptionsLocal);

I have control of the server, so first thought would be to have a unique port for each environment.

But I'm not sure how to create a channel to our azure service then, I tried with the IP from the URL, but then I get an connection lost exception. It's a https connection.

Channel(host="backendDev.azure.com", port=443)
Traceback (most recent call last):
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\grpclib\client.py", line 368, in recv_initial_metadata
    headers = await self._stream.recv_headers()
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\grpclib\protocol.py", line 342, in recv_headers
    await self.headers_received.wait()
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\asyncio\locks.py", line 214, in wait
    await fut
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Dev/pythonProject/TestGrpc/main.py", line 43, in main
    await read_version()
  File "C:/Dev/pythonProject/TestGrpc/main.py", line 12, in read_version
    data = await backend.storage_manager.read_db_version(database_type_enum=DatabaseTypeEnum.DATABASE_TYPE_ENUM_MASTER_DATABASE)
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\invisio_backend\Protos\Interfaces\__init__.py", line 2459, in read_db_version
    return await self._unary_unary(
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\betterproto\grpc\grpclib_client.py", line 85, in _unary_unary
    response = await stream.recv_message()
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\grpclib\client.py", line 425, in recv_message
    await self.recv_initial_metadata()
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\grpclib\client.py", line 367, in recv_initial_metadata
    with self._wrapper:
  File "C:\Users\mhj\AppData\Local\Programs\Python\Python310\lib\site-packages\grpclib\utils.py", line 70, in __exit__
    raise self._error
grpclib.exceptions.StreamTerminatedError: Connection lost
vmagamedov commented 2 years ago

Try this way:

Channel(host="backendDev.azure.com", port=443, ssl=True)
                                               ~~~~~~~~

https://grpclib.readthedocs.io/en/latest/client.html#secure-channels

CaptTwigg commented 2 years ago

Now I get an GRPCError

grpclib.exceptions.GRPCError: (<Status.UNKNOWN: 2>, "Received :status = '426'", None)

Tried https://grpclib.readthedocs.io/en/latest/errors.html#error-details but details is None

CaptTwigg commented 2 years ago

The problem seems to be that the cloud service is running http 1.1 with UseGrpcWeb and only http 2 is supported. Could this be correct?

vmagamedov commented 2 years ago

Maybe there is some kind of misconfiguration on the server-side or a bug like this: https://github.com/dotnet/aspnetcore/issues/14139

grpclib sends only HTTP/2 requests. So the server must support original (not grpc-web) HTTP/2-based gRPC protocol.

tmsrikanth commented 1 year ago

The connection is not secure , hence the error. Is the service deployed as part of kube cluster in AKS. They would have used ingress to expose the service endpoint. Try to get the client certificate and try a secure channel creation.