rocker-org / rocker

R configurations for Docker
https://rocker-project.org
GNU General Public License v2.0
1.46k stars 271 forks source link

Use reticulate and python in docker container to deploy plumber api #501

Closed MislavSag closed 2 years ago

MislavSag commented 2 years ago

In nutshell, I try to use reticulate inside plumber API function. I explained everything in more detail on the link:

https://stackoverflow.com/questions/73632744/use-reticulate-and-python-in-docker-container-to-deploy-plumber-api

MislavSag commented 2 years ago

I have the solution. Here are the files: docker files (changes R packages you want to install, but need reticulate):

# Dockerfile
FROM rocker/r-base:4.2.1

# install the linux libraries needed for plumber
RUN apt-get update --fix-missing \
    && apt-get install -y \
        ca-certificates \
        build-essential \
        libprotobuf-dev \
        protobuf-compiler \
        cmake \
    libglib2.0-0 \
        libxext6 \
      libsm6  \
      libxrender1 \
      libcurl4-gnutls-dev \
        libxml2-dev \
        libsndfile1 \
        libx11-dev \
        libatlas-base-dev \
        libgtk-3-dev \
        libboost-python-dev \
        libsodium-dev \
        ffmpeg \
        python3-audioread \
        libssl-dev \
        openssl \
        python3-openssl \
        pkg-config

# RUN apt-get update -qq && apt-get install -y \
#    libssl-dev \
#    libcurl4-gnutls-dev \
#    libsodium-dev

# create the application folder
RUN mkdir -p ~/application

# copy everything from the current directory into the container
COPY "/" "application/"
WORKDIR "application/"

# open port 8080 to traffic
EXPOSE 8080

# install packages
RUN R -e "install.packages('stats')"
RUN R -e "install.packages('plumber')"
RUN R -e "install.packages('utils')"
RUN R -e "install.packages('theft')"
RUN R -e "install.packages('quarks')"
RUN R -e "install.packages('tvgarch')"
RUN R -e "install.packages('mlr3')"
RUN R -e "install.packages('mlr3pipelines')"
RUN R -e "install.packages('mlr3filters')"
RUN R -e "install.packages('mlr3fselect')"
RUN R -e "install.packages('mlr3learners')"
RUN R -e "install.packages('mlr3tuning')"
RUN R -e "install.packages('fastICA')"
RUN R -e "install.packages('bestNormalize')"
RUN R -e "install.packages('mlr3verse')"
RUN R -e "install.packages('data.table')"
RUN R -e "install.packages('exuber')"
RUN R -e "install.packages('remotes')"
RUN R -e "install.packages('ranger')"
RUN R -e "remotes::install_github('https://github.com/MislavSag/finfeatures')"
RUN R -e "remotes::install_github('https://github.com/mlr-org/mlr3extralearners')"

# install python and packages
RUN apt-get -y install python3 python3-venv python3-pip
RUN python3 -m venv /home/rstudio/venv
RUN /home/rstudio/venv/bin/pip3 install --upgrade pip setuptools wheel
RUN /home/rstudio/venv/bin/pip3 install tsfel
RUN /home/rstudio/venv/bin/pip3 install scipy==1.8.1

# when the container starts, start the main R script
ENTRYPOINT ["Rscript", "execute_plumber.R"]

plumber file example:

# plumber.R

library(plumber)
library(exuber)
library(finfeatures)
library(data.table)
library(mlr3)
library(mlr3verse)
library(mlr3extralearners)
library(mlr3pipelines)
library(mlr3filters)
library(mlr3fselect)
library(mlr3learners)
library(mlr3tuning)
library(tvgarch)
library(runner)
library(theft)
library(quarks)
library(reticulate)
library(feasts)
# learners
library(ranger)
library(stats)
library(fastICA)
library(bestNormalize)

# import mlr3 models
model <- readRDS(file = 'hftmlr_model.rds')

# python virtual environment
ve <- tryCatch(reticulate::use_virtualenv("/home/rstudio/venv"), error = function(e) e)
print(ve)

# reticulate::use_python("C:/ProgramData/Anaconda3/envs/mlfinlabenv/python.exe", required = TRUE)

#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg="") {
  list(msg = paste0("The message is: '", msg, "'"))
}

#* Plot a histogram
#* @serializer png
#* @get /plot
function() {
  rand <- rnorm(100)
  hist(rand)
}

#* Return the sum of two numbers
#* @param a The first number to add
#* @param b The second number to add
#* @post /sum
function(a, b) {
  as.numeric(a) + as.numeric(b)
}

Execute plumber file:

# Execute plumber
plumber::plumb(file="plumber.R")$run(host = '0.0.0.0', port = 8080)