Client-Server¶
Rserve is currently the default solution when looking
for a server solution for R, but rpy2
can be used
to develop very easily one’s own server, tailored to answer
specific requirements. Such requirements can include for example
access restriction, a security model, access to subsets of the R
engine, distribution of jobs to other servers, all of which
are currently difficult or impossible to achieve with R serve.
The pyRserve
package addresses the connection to Rserve
from Python, and although it frees one from handling the R server is
also constrains one to use Rserve.
Simple socket-based server and client¶
Server¶
An implementation of a simplistic socket server listening on a given port for a string to evaluate as R code is straightforward with Python’s SocketServer module.
Our example server will be in a file rpyserve.py, containing the following code.
import SocketServer
import sys
import rpy2.robjects as robjects
class MyTCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
# self.rfile is a file-like object created by the handler;
# we can now use e.g. readline() instead of raw recv() calls
self.data = self.rfile.readline().strip()
# verbose server
print "%s wrote:" % self.client_address[0]
print self.data
# evaluate the data passed as a string of R code
results = robjects.r(self.data)
# return the result of the evaluation as a string
# to the client
self.wfile.write(str(results))
if __name__ == "__main__":
HOST, PORT = "localhost", int(sys.argv[1])
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
Running a server listening on port 9090 is then:
python rpyserve.py 9090
Client¶
Using Python’s socket module, implementing a client is just as easy. We write the code for ours into a file rpyclient.py:
import socket
import sys
HOST, PORT = sys.argv[1].split(":")
PORT = int(PORT)
data = " ".join(sys.argv[2:])
# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to server and send data
sock.connect((HOST, PORT))
sock.send(data + "\n")
# Receive data from the server and shut down
received = sock.recv(1024)
sock.close()
print "Sent: %s" % data
print "Received: %s" % received
Evaluating R code on a local server as defined in the previous section, listening on port 9090 is then:
python rpyclient.py localhost:9090 'R.version'
In this example, the client is querying the R version.