diff --git a/.gitignore b/.gitignore index 7b732e7..bbb6a19 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .RData .Ruserdata .DS_Store +test.R diff --git a/Dockerfile b/Dockerfile index 3f917a2..e2af811 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,24 @@ -FROM trestletech/plumber -MAINTAINER decryptr - -# Install Python. -RUN apt-get update || apt-get update +FROM rocker/tensorflow +MAINTAINER decryptr RUN \ - apt-get update && apt-get install -y apt-transport-https && \ - apt-get install -y python python-dev python-pip python-virtualenv libssl-dev && \ + apt-get update && \ + apt-get install -y apt-transport-https && \ + apt-get install -y libssl-dev libjpeg-dev libmagick++-dev && \ rm -rf /var/lib/apt/lists/* - -# Install ML packages -RUN R -e "install.packages('plumber')" -RUN R -e "install.packages('yaml')" -RUN R -e "install.packages('base64enc')" -RUN R -e "install.packages('openssl')" -RUN R -e "install.packages('devtools')" -RUN R -e "install.packages('base64enc')" -RUN R -e "install.packages('reticulate')" -RUN R -e "install.packages('tensorflow')" -RUN R -e "tensorflow::install_tensorflow()" -RUN R -e "devtools::install_github('rstudio/keras')" -RUN R -e "keras::install_keras()" +RUN Rscript -e "install.packages(c('plumber', 'yaml', 'base64enc', 'remotes'))" +RUN Rscript -e "remotes::install_github('rstudio/reticulate')" +RUN Rscript -e "remotes::install_github('rstudio/tensorflow')" +RUN Rscript -e "remotes::install_github('rstudio/keras')" # Install captcha-breaking captchas -RUN R -e "devtools::install_github('decryptr/decryptrModels')" -RUN R -e "devtools::install_github('decryptr/decryptr', ref = 'raw-reading-support')" +RUN Rscript -e "remotes::install_github('decryptr/decryptr')" COPY api.R api.R COPY keys.yaml keys.yaml # Run -EXPOSE 8000 -CMD ["api.R"] +EXPOSE 8080 + +CMD ["Rscript", "-e", "pr <- plumber::plumb('api.R'); pr$run(host='0.0.0.0', port=8080)"] diff --git a/README.md b/README.md index ecab302..79886b4 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ To serve the API on [http://localhost:80](http://localhost:80) with no load balancing, run the command below: ``` -docker build api . -docker run -p 80:8000 api +docker build -t api . +docker run -p 80:80 api ``` ## Adding a new key @@ -24,5 +24,57 @@ source("key-generator.R") key_generator("name-of-the-endpoint") ``` -The function will make necessary modifications to `keys.yaml`. They generated key will be printed to the console. +The function will make necessary modifications to `keys.yaml`. They generated key will be printed to the console. **Note** The key is printed only once. +## Updating the endpoint + +On shell, type: + +``` +docker build -t dfalbel/api . +docker push dfalbel/api +gcloud compute instances create-with-container decryptr \ + --project=decryptr-196601 \ + --container-image dfalbel/api \ + --machine-type g1-small \ + --tags http-server \ + --address 104.197.127.86 \ + --metadata startup-script='#! /bin/bash +sudo iptables -w -A INPUT -p tcp --dport 80 -j ACCEPT +EOF +' +``` + +You must have `gcloud` CLI installed. + +## Using from R + +You can use the API from with the following chunk of code: + +``` +library(magrittr) + +# parameters +arq <- "https://decryptr.netlify.com/img/sample-captcha.png" +key <- "your-api-key" + +# converting the image to base64 + +img <- arq %>% + readr::read_file_raw() %>% + base64enc::base64encode() + +# post request +res <- httr::POST( + "https://decryptr.now.sh/rfb", + body = list( + img = img, + key = key + ), + encode = "json" +) + +httr::content(res) +``` + +Please visit [decryptr.netlify.com](http://decryptr.netlify.com) fore more info and to obtain your own key. diff --git a/api.R b/api.R index 9c32619..c60c664 100644 --- a/api.R +++ b/api.R @@ -2,17 +2,65 @@ library(decryptr) library(base64enc) model_rfb <- load_model("rfb") +model_rsc <- load_model("rsc") +model_cadesp <- load_model("cadesp") +model_nfesp <- load_model("nfesp") + keys <- yaml::read_yaml("keys.yaml") +#* @get / +root <- function() { + "hello world" +} + #* @post /rfb rfb <- function(img, key){ key <- openssl::sha256(key) - if(!key %in% keys$rfb | is.null(key) | is.na(key)) { + if(!key %in% keys | is.null(key) | is.na(key)) { stop("Not authorized. Get an api key from decryptr.com.br") } img_decoded <- base64enc::base64decode(img) + message(Sys.time(), ": rfb") decrypt(img_decoded, model_rfb) } +#* @post /rsc +rsc <- function(img, key){ + + key <- openssl::sha256(key) + if(!key %in% keys | is.null(key) | is.na(key)) { + stop("Not authorized. Get an api key from decryptr.com.br") + } + + img_decoded <- base64enc::base64decode(img) + message(Sys.time(), ": rsc") + decrypt(img_decoded, model_rsc) +} + +#* @post /cadesp +cadesp <- function(img, key){ + + key <- openssl::sha256(key) + if(!key %in% keys | is.null(key) | is.na(key)) { + stop("Not authorized. Get an api key from decryptr.com.br") + } + + img_decoded <- base64enc::base64decode(img) + message(Sys.time(), ": cadesp") + decrypt(img_decoded, model_cadesp) +} + +#* @post /nfesp +nfesp <- function(img, key){ + + key <- openssl::sha256(key) + if(!key %in% keys | is.null(key) | is.na(key)) { + stop("Not authorized. Get an api key from decryptr.com.br") + } + + img_decoded <- base64enc::base64decode(img) + message(Sys.time(), ": nfesp") + decrypt(img_decoded, model_nfesp) +} diff --git a/example.Rmd b/example.Rmd new file mode 100644 index 0000000..ebf1914 --- /dev/null +++ b/example.Rmd @@ -0,0 +1,45 @@ +--- +title: "Untitled" +output: html_document +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set(echo = TRUE) +``` + +Suppose I have 2 overloaded functions in the C++ library I am creating wrapers for R: + +```{Rcpp} +int fun (int i) { + return i + 1; +} + +int fun (int i, int j) { + return i + j +} +``` + +I am writing the C++ code like this: + +```{Rcpp} +int my_wraper (int i, Rcpp::Nullable j) { + + int out; + + if (j.isNull()) { + out = fun(i); + } else { + out = fun(i, j); + } + + return out; +} +``` + +The problem is that this quickly becomes tedious if the function has 10 +different signatures. Would there be any way to + + + + + diff --git a/key-generator.R b/key-generator.R index 57cfdb4..cc3e3df 100644 --- a/key-generator.R +++ b/key-generator.R @@ -5,3 +5,4 @@ key_generator <- function(endpoint) { yaml::write_yaml(keys, file = "keys.yaml") new_key } + diff --git a/keys.yaml b/keys.yaml index 1e6e6ea..68fd835 100644 --- a/keys.yaml +++ b/keys.yaml @@ -1,7 +1,20 @@ -rfb: - ef556689177dbe281139a5688162f54166127c83746a83c87b872605621aa156 - ef556689177dbe281139a5688162f54166127c83746a83c87b872605621aa156 - b934527d8d59be4766e43db6c9de039871ddcea33c948bcf59ee5ed29fdc1f4f -tjsp: +- 5ead3acec819ee56b15a9d1d9ddd64044ee1fe80f12333a1724ba1febbeb7d84 +- 20f8cad884b29ffd9a926633a95594d71e5c38137123afecac14a0f8a0020afb +- 370313260a42bc2d8e78f423d10768526defe4653b02ce4eac9faccc01791153 +- 8a1c837e472bff753c204e391d23bd3827c0c8a1f4ba6b2f509050a6d7a26ebc +- 89a41eb33e7921d09d2e6016bfc6952daa421a799acd7a0425d63850d483b170 +- 43582a1663f54bf4cce2efe1743613f78d1226f70c8251d799c1b1fdce7517c1 +- cec6341c56c90c8fb195a6b0dc398364e9b4f7becf28e2660de4dd7022bd4aba +- 425d030a3ea9bbac450d36aafc5b3be0137aafc66573a43b68a4dcc2659bb246 +- b31a3e607c9233304beca5d2e207f202e9cdfb8e62446e242d85472f415dd9c6 +- 92de28b6fb134ed15a51d3e2a8283d5c1570b4eb0c2a12656db1953907946b15 - 500b9353182dbe693eba1a6c242108103dcef7954d1bdab3e622a0bda3187474 - d28be9f24a8ffc0e7698e87e9fa84c7a469135561b9294ba66091658bb413856 +- a62d0d5f6c6d541028e5af059a18da585888550d815fe0a1289671433e2a7986 +- d7abeb4ab20aab42c3a54f92f37d98330f2cbd1d7e3804f282eaa265d35dede9 +- 9ac78bf7017408c0c1c803c7ff3481872142cb35f7cff1535f7c09f902192436 +- 805f61f603b71bb4ea2fcf1b4e0f7e81aa7dce862bf0cc8abc8e136d0670b1c7 +- 611a69d04ea3b5daf033a09c74fb1d9c2229262adf375b9b80fab11fa636c3fd