In this blog post, we shall explore opensource application called OpenCPU to enable remote procedure calls of any R/Python object. That means we can invoke any object on the server with a simple API call

OpenCpu application lets you create and retrieve R objects via http(s). OpenCPU creates a server for R objects.

Expert Opinion about OpenCPU

Applies to R and Python. Python functions have to be wrapped within R using reticulate package

Statisticians/Data Scientists/ Data Analysts - who need to host several functions for inference/access on a server, but don't want to write REST endpoint code for each of those objects. With OpenCPU all the installed libraries are ready for remote calls

Solution Architects - who want to efficiently make use of their server resources. OpenCPU does not require a dedicated end point process running all the time. Once the request is made,an object gets created. This object can then be reused. This approach avoids unnecessary consumption of CPU cycles, when the same program needs to be run

This blogger highlights what are the disadvantages of using Shiny

  1. Can't reuse the R model (back-end) "as is" in other applications
  2. Can't tap into the almost unlimited existing Javascript, CSS and HTML frameworks for building the front-end (View)
  3. Completely dependent on the Shiny vendor if I'd like to scale the web application to higher levels in terms of speed, scalability and costs

OpenCPU addresses these concerns and also offers parallel computing and asynchronous requests. OpenCPU offers business friendly licensing.

Compared to Plumber - another popular approach for REST endpoint - I see one big advantage with OpenCPU.You need not write any extra code to set up a REST endpoint. Literally all your function in every installed package are ready to be called with OpenCPU. Plumber is awesome too.

Twitter link

Here is a link to a hosted working example. I encourage you to try examples here to get an idea of how OpenCPU works.

Another demo of how any R object can be called using REST API's

I prefer using Docker approach to install OpenCPU. With Docker you can eliminate the "it works on my machine" problem once and for all.This means that your images run the same no matter which server or whose laptop they are running on.

Here is simple intro to Docker.Here are some benefits of using Docker

.All you need to know is this Docker setup sequence.

My goal was to create a openCPU server on cloud. But before hosting on cloud, I wanted to get the setup working on my laptop. For that I copied sample Dockerfile for Opencpu from this site.

Step1: Copied Dockerfile from here

# Use builds from launchpad
FROM opencpu/base

# Install development tools
RUN \
  apt-get install -y rstudio-server r-base-dev sudo curl git libcurl4-openssl-dev libssl-dev libxml2-dev libssh2-1-dev

# Workaround for rstudio apparmor bug
RUN echo "server-app-armor-enabled=0" >> /etc/rstudio/rserver.conf

CMD service cron start && /usr/lib/rstudio-server/bin/rserver && apachectl -DFOREGROUND

This Dockerfile is based on opencpu/base image that was created already. We are creating an instance of an Ubuntu Linux machine and installing rstudio on it.rstudio + opencpu make it a nice workflow.

Step2: Now build an image from the Dockerfile

docker build -t my_opencpu_image .

This docker command refers to local Dockerfile in current folder, and builds an image. Note that the dot is required at the end. -t flag sets tag for your Docker image

Step3: Now run the image with docker run command. Note that we are passing in the name of the image we used in step2

docker run --name my_container -t -p 8004:8004 my_opencpu_image

Check if container is running with this command

Pavans-MBP:rstudio pavanmirla$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                     NAMES
cc985c504fbc        opencpu_rstudio     "/bin/sh -c 'service..."   5 hours ago         Up 4 hours          80/tcp, 443/tcp, 0.0.0.0:8004->8004/tcp   mybox

Open this URL. This is a test app that OpenCPU author developed to demonstrate how R functions can be executed with API calls - such as http GET and POST

Since we used Docker for opencpu + rstudio, you can access rstudio from the localhost url. This setup is quite handy. We can now create packages through the web interface and then call that function for results via an HTTP call. HTTP request could be from a web application for instance.

Example of GET Call

Example of POST call

There are several other examples in this website

In this example below, a csv file is uploaded using read.csv function and a dataframe object gets created- that will be used to create a plot in the following example

Example to demonstrate how objects can be reused. Hence facilitating chaining of remote procedure calls. Here we are reusing the dataframe object created above to create a plot using ggplot library

This is my workflow. Not a standard, but this satisfies my needs.

Step1: Create your Docker file with COPY and RUN Rscript commands as below.

docker build -t opencpu_oct .

 
# Use builds from launchpad
FROM ubuntu:18.04

ENV DEBIAN_FRONTEND noninteractive

# Install and 'hold' opencpu-server so that the docker image can be tagged
RUN \
  apt-get update && \
  apt-get -y dist-upgrade && \
  apt-get install -y software-properties-common && \
  add-apt-repository -y ppa:opencpu/opencpu-2.1 && \
  apt-get update && \
  apt-get install -y opencpu-server && \
  apt-mark hold opencpu-server


# Prints apache logs to stdout
RUN \
  ln -sf /proc/self/fd/1 /var/log/apache2/access.log && \
  ln -sf /proc/self/fd/1 /var/log/apache2/error.log && \
  ln -sf /proc/self/fd/1 /var/log/opencpu/apache_access.log && \
  ln -sf /proc/self/fd/1 /var/log/opencpu/apache_error.log

# Set opencpu password so that we can login
RUN \
  echo "opencpu:opencpu" | chpasswd

# Apache ports
EXPOSE 80
EXPOSE 443
EXPOSE 8004

## create directories
RUN mkdir -p /01_data
RUN mkdir -p /02_code
RUN mkdir -p /03_output

COPY install_packages.R /02_code/install_packages.R
## install R-packages
RUN Rscript /02_code/install_packages.R

# Start non-daemonized webserver
CMD service cron start && apachectl -DFOREGROUND

List names of packages to be installed in to install_packages.R file. This file will be copied since you have COPY command in your Dockerfile

Example of my install_packages.R file

install.packages("readr")
install.packages("dplyr")
install.packages("ggplot2")
install.packages("forcats")

Step2:

Refer to R API Object section

Watch this video to understand how reusable objects get created for each RPC call

Checkout this observable hq notebook that demonstrates how javascript client package can be used to query an R server and execute commands remotely and retrieve data. Here is link to Javascript client

Continuous Integration with Travis

How to mount volumes to copy files to Docker image script on container start.

Reachout at this address : pavanmirla@perceptron.solutions