How to deploy gRPC server/client to heroku? - python

I deployed my python gRPC server to Heroku and was wondering how I could test it with a local Python client.
server.py
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
icp_pb2_grpc.add_MyServicer_to_server(MyServicer(), server)
server_port = os.environ.get('PORT', 50051)
server.add_insecure_port('[::]:'+ str(server_port))
server.start()
print("==== SERVER RUNNING =====")
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
client.py
def run():
# Is the channel url correct?
channel = grpc.insecure_channel('https://www.HEROKUURL.com:50051')
stub = my_grpc.MyStub(channel)
file = _get_file_content()
response = stub.Predict(icp_pb2.MyRequest(file_content=file))
print("received: " + response.results)
I am using the client from my computer and am not receiving any response from the server. I am able to successfully communicate with the server if it is launched locally. What am I doing wrong?

Heroku does not support HTTP 2. On the other hand, GRPC uses a http/2 based transport. I think that's why you can connect it locally but not from Heroku.

Related

Flask SocketIO web app refuses to accept connections from python file

I am trying to send some data to a Flask app using web sockets. Never done something like this so I might be doing something very wrong but so far I haven't been able to accept a single connection.
For the moment I have 2 python files, server.py and client.py.
server.py starts the flask server and the web socket, then client.py should be able to connect to it, send a message, which is printed out to the server console, then the server should echo that message back where it will be received by the client and print to the client console.
However right now I am getting a Handshake status 400 BAD REQUEST error when the client tries to connect.
Here is the code I'm using:
server.py :
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hi'
socketio = SocketIO(app)
#app.route('/')
def sessions():
return "Hello World"
#socketio.on('message')
def handle_my_custom_event(mes):
print('received my event: ' + str(mes))
socketio.emit('my response', mes)
if __name__ == '__main__':
socketio.run(app, debug=True)
client.py :
import websocket
websocket.enableTrace(True)
ws = websocket.create_connection("ws://localhost:5000")
print("Sending 'Hello, World'...")
ws.send("Hello, World")
print("Sent")
print("Receiving...")
result = ws.recv()
print("Received '%s'" % result)
ws.close()
I think there is something wrong with the server.py file but, i've been flowing the Flask-SocketIO docs and its pretty much identical to their getting started example. But then again, I also don't know enough about this so i have no real idea where the problem lies.
Any help is appreciated thank you!
The problem is with your client. Websocket and socket.io aren't the same, socket.io protocol can use websockets under the hood but you cannot just connect with websocket client to socket.io server.
What you want to use is socket.io client.
And if you don't mind I highly encuorage you to use FastAPI instead of flask. It's much simpler, faster and have much better documentation. Here you can find complete and working example of websocket server and client with FastAPI

rpyc server call client method

I am currently using rpyc for constructing a server and multiple clients that will connect to it. I have data in the clients that I would like to push to the server for further processing, and I would like to do it with the server calling a client method whenever the client connects to the server. From their tutorial, it says that clients can expose their service to the server, but I am getting errors.
Code for my server:
import rpyc
class TestService(rpyc.Service):
def on_connect(self, conn):
conn.root.example()
if __name__ == "__main__":
from rpyc.utils.server import ThreadedServer
t = ThreadedServer(TestService, port=18861, auto_register=True)
t.start()
Code for my client:
import rpyc
class ClientService(rpyc.Service):
def exposed_example(self):
print "example"
if __name__ == "__main__":
try:
rpyc.discover("test")
c = rpyc.connect_by_service("test", service=ClientService)
c.close()
except:
print "could not find server"
The client is able to connect to the server, but there will be an exception in thread and an error: raise EOFError("stream has been closed"). It is complaining about the line conn.root.example() and I don't know what the correct syntax would be, and the tutorial did not specify at all.
Any help will be much appreciated!

How to send a message from server to client freely when using python diesel?

When a client send a message to a server, the server can send back a massage simultaneously.
'''Simple echo server.
'''
from diesel import Application, Service, until_eol, send
def hi_server(addr):
while 1:
inp = until_eol()
if inp.strip() == "quit":
break
send("you said %s" % inp)
app = Application()
app.add_service(Service(hi_server, 8013))
app.run()
if i want to send a message from a server to a client when no requesting from the client, how to do it?

iOS - How to connect to flask server using flask-socketIO with out namespace?

I'm building an iOS app which receive data from socket. I'm quite new to things about socket.
I use flask framework to build my server. To implement the long poll, I find the flask-socketIO package. However I haven't found some useful tutorial.
I use CocoaAsyncSocket to conncet and send data to the server and it works fine when I test a naive python socket. Code:
from socket import *
from time import ctime
serverClient = socket(AF_INET, SOCK_STREAM)
HOST='127.0.0.1'
PORT=8808
BUFSIZ=1024
ADDR=(HOST, PORT)
serverClient.bind(ADDR)
serverClient.listen(5)
while True:
print('waiting for input')
clientSocket, addr = serverClient.accept()
print('connect from ', addr)
while True:
try:
data= clientSocket.recv(BUFSIZ)
except:
print(e)
clientSocket.close()
break
if not data:
break
s='Hi,you send me :[%s] %s' %(ctime(), data.decode('utf8'))
clientSocket.send(s.encode('utf8'))
print([ctime()], ':', data.decode('utf8'))
clientSocket.close()
serverClient.close()
However, I don't know how to put it together with my flask server. This is also why I try flask-socketIO.
Under the instruction of the document, I implement
#socketio.on('connect', namespace='/test')
def test_connect():
emit('my response', {'data': 'Connected'})
in my views.py.
Can I do without specifying the namespace? But without specifying a namespace, the default one is '/', will it conflict with my home directory?
Socket.IO is a specialized protocol, not a plain networking library. If you are going to use Socket.IO on your server, then you need to use a Socket.IO client on your iOS device, such as this one: https://github.com/socketio/socket.io-client-swift.

Why is my server working locally, but not on heroku?

This is the code for my server.
import os
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
class IphoneChat(Protocol):
def connectionMade(self):
#self.transport.write("""connected""")
self.factory.clients.append(self)
print "client connected"
def connectionLost(self, reason):
self.factory.clients.remove(self)
print "client disconnected"
def dataReceived(self, data):
print "data is ", data
for c in self.factory.clients:
c.message(data)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.protocol = IphoneChat
factory.clients = []
ON_HEROKU = os.environ.get('ON_HEROKU')
if ON_HEROKU:
# get the heroku port
port = int(os.environ.get('PORT', 17995))
else:
port = 3000
print "Iphone Chat server started on port: "
print port
reactor.listenTCP(port, factory)
reactor.run()
The code works perfectly locally, test it out for yourself. Just create a telnet communication via local host on port 3000 and you can seamlessly send and receive data.
However once I push this code to heroku and run the server, the server runs and prints out which port it is listening to, however when I try and create a connection to the server and send data, it just doesn't seem to pickup that a client is connected or send and receive data.
Can anyone resolve the issue?
I can't comment (not enough rep) but I think you aren't connecting to your app correctly. Usually to connect to heroku apps you connect to http://<appname>.herokuapp.com. I don't think you can directly connect to your app because of how heroku's routing system works.
See https://devcenter.heroku.com/articles/http-routing

Categories