Code Monkey home page Code Monkey logo

beakr's People

Contributors

hmrtn avatar johnwilshire avatar jonathancallahan avatar tabrasel avatar xevion avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

beakr's Issues

get local_examples/test_repeater_beakr.R to work

At the outset, our goal was to create a replacement for the deprecated jug package.

Some of the joy of using jug was that you didn't have to know much about unix or web servers and could just write some R code.

I have created two scripts to demonstrate what was possible with jug and what I would like to be possible with beakr:

  • local_executables/test_repeater_beakr.R
  • local_executables/test_repeater_jug.R

Looking at the diff shows how easy I was hoping it would be to convert our old web services:

$ diff test_repeater_jug.R test_repeater_beakr.R
8c8
< library(jug)
---
> library(beakr)
11c11
< jug() %>%
---
> newBeakr() %>%
15c15
<   get("/", function(req, res, err) {
---
>   GET("/", function(req, res, err) {
36c36
<   get("/repeater", function(req, res, err) {
---
>   GET("/repeater", function(req, res, err) {
88c88
<   simple_error_handler_json() %>%
---
>   errorHandler() %>%
92,93c92
<   serve_it()
---
>   startBeakr(daemon = FALSE)

The ** jug** version works as expected with a simple ability to walk through the debugger and quit with a single click on the stop button. It also generates desired output in a variety of formats and an informative, json formatted error message if times > 10.

The beakr version doesn't currently work and I don't understand why. It also has a strange behavior where I have to click the stop button 3 times to get it to end.

We should talk at some point so that I can understand what has changed in the overall design and why. Perhaps there is a better way to rewrite the code I am familiar with. But it has to be a great improvement to justify any refactoring it will force on us. We have several complex, operational web services that currently depend on the deprecated jug package and my primarily goal is to support those going forward with a non-deprecated package.

I see a couple of good options at this point:

  • Educate me about how beakr works -- perhaps the functionality I want is already there but I just need different syntax.
  • Add features to beakr so that it can work in the way I expect.
  • If beakr has some super-cool functionality but is incompatible with what I want, perhaps we should release beakr and create a second MazamaWebUtils package that has the maintainable rump of the jug package I'm looking for.

Comparison with plumber

Apologies for the unsolicited question but, having tested and been impressed at the 'hello world' example, I'm wondering how this compares with the plumber package. Context: @layik and I have used plumber as the basis of a package to visualise and serve geographic data, and am wondering if this package could have advantages as an R backend...

Thanks for sharing, looks like an impressive project with great potential!

cors() not working as described

I have pushed up beakr 0.4 to GitHub but cannot get the cors() functionality to work. It may only be a documentation issue but, if so, that means that the core() function arguments need a LOT more description.

I tried running the following in RStudio:

library(beakr)

newBeakr() %>% 
  
  cors() %>%
  
  httpGET(path = "/hi", function(req, res, err) {
    print("Hello, World!")
  }) %>% 
  httpGET(path = "/bye", function(req, res, err) {
    print("Farewell, my friends.")
  }) %>% 
  
  handleErrors() %>%
  
  listen(host = "127.0.0.1", port = 25118) 

It works if I comment out the cors() %>% line but fails if I uses it with the following error message:

Error in ans[ypos] <- rep(yes, length.out = len)[ypos] : 
  replacement has length zero

Here is my environment:

> sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.7

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] beakr_0.4.0

loaded via a namespace (and not attached):
[1] Rcpp_1.0.6            rstudioapi_0.13       magrittr_2.0.1       
[4] webutils_1.1          hms_0.5.3             lattice_0.20-41      
[7] R6_2.5.0              rlang_0.4.10          stringr_1.4.0        
[10] tools_4.0.2           rgdal_1.5-18          grid_4.0.2           
[13] lambda.r_1.2.4        futile.logger_1.4.3   ellipsis_0.3.1       
[16] tibble_3.0.6          lifecycle_0.2.0       crayon_1.3.4         
[19] readr_1.4.0           formatR_1.7           later_1.1.0.1        
[22] base64enc_0.1-3       vctrs_0.3.6           promises_1.1.1       
[25] futile.options_1.0.1  sp_1.4-5              stringi_1.5.3        
[28] compiler_4.0.2        pillar_1.4.7          MazamaCoreUtils_0.4.7
[31] jsonlite_1.7.2        httpuv_1.5.5          pkgconfig_2.0.3      

beakr.verbose should be a class field, not a global option

I think it highly appropriate that we have some debugging options but they shouldn't be global through the use of options("beakr.verbose" = FALSE). Instead, the R6 class should have a verbosefield with an associated getter and setter.

review function names `utils.R` for parts of speech

We would like to have an overall naming scheme that uses nouns for classes and variables and verbs for methods and functions. Any exceptions to this rule, like static() should adhere to some internal standard, i.e. dropping create from createNewBeaker() to get just newBeaker().

Add FUN parameter to handleErrors()

Developers should be able to specify their own error handling methods instead of using the default jsonError() method called by handleErrors().

reformatted code snippets should work if copy-pasted

Several functions currently have examples in the form of preformatted code snippets. We aren't using @example because we don't actually want to start up a web service.

To encourage people to use a new package it is really nice to have examples that can just be copy-pasted into the RStudio console where a user can observe what happens. The code examples are currently structured as pseudo-code where a user has to modify things before they can be run. This acts as a barrier to first-time users.

All examples should instead modify the existing example in README.md using comment lines to explain rather than pseudo-code. The goal is to have all examples work if copy-pasted into the RStudio console.

library(beakr)

# Create a new beakr server
newBeakr() %>% 

  # Respond to GET requests at the "/hi" route
  httpGET(path = "/hi", function(req, res, err) {
    print("Hello, World!")
  }) %>% 
  
  # Respond to GET requests at the "/bye" route
  httpGET(path = "/bye", function(req, res, err) {
    print("Farewell, my friends.")
  }) %>% 
  
  # Start the server on port 25118
  listen(host = "127.0.0.1", port = 25118) 

"try-err" ==> "try-error"

Router.R has: "try-err" %in% class(result) which won't match. It needs to be "try-error" %in% class(result)

complete "Web Frameworks for R" blog post

The blog has a draft article titled "Web Frameworks for R" which is partly finished. It should be completed with brief assessments of the following packages:

  • Shiny
  • fiery -- couple of sentences
  • ambiorix -- couple of sentences
  • server -- couple of sentences
  • dash -- couple of sentences.

This article is not supposed to be a detailed review but rather a brief comparison for those wondering whether to try it out or not. It can unabashedly advocate for beakr as having the right set of features for Mazama Science: we are comfortable with web protocols and html/css/javascript and need an R web framework that is simple, robust and flexible.

Additional examples/tests

We need to have examples (at least in local_examples/) that demonstrate how to use beakr as a replacement for jug in our existing web services. By far the most common use case is to attach functions to URL paths. The functions will typically:

  • accept req, res, err
  • extract parameters from a browser initiated GET request
  • if not already found in a cache directory: 1) run a bunch of R code; and 2) write a file to disk
  • read a file from disk
  • return one of: 1) a blob of json with the file URL; or 2) the file itself

File types that we currently serve include:

  • json
  • text
  • csv
  • pdf
  • png
  • html

But we want to be able to serve up just about anything along with the proper mime type. (See the mime package.)

object documentation

Although all the necessary roxygen2 comments seem to be in place, no documentation is shown in RStudio for the objects Beakr, Request, Response, etc.

We need to figure out how to document R6 objects so that this documentation becomes visible in the installed package.

docker article

We need an article that walks people through the basics of setting up a dockerized web service.

startBeakr() defaults

I was surprised that startBeakr() appears to default to daemon = TRUE.

I think this is not the behavior we want as it requires the user to be familiar with UNIX systems and to trust themselves with killing processes. (I'm still not sure myself about how dangerous kiilAll() might be.)

A better default would be daemon = FALSE so that development and testing can consist of:

  • set a breakpoint in the beakr R script
  • source the script
  • poke at the web page and get dropped into the beakr script in debug mode
  • walk through the script
  • click on the stop button (red square) to have bear shut down

And we need to make sure that this new R6 style documentation mentions the default settings somewhere. I had to experiment and read the source code to understand what the default settings were for startBeakr()`.

serveStaticFiles() fails to server .html

This version of beakr serves .png and .txt files fine. But when asked for a .html file it always returns "3c".

Here is a script that reproduces the error:

# ===== Create output files ====================================================

if ( FALSE ) {

  # Create a .txt file in temp directory
  dir.create("./output")
  textString <-
"
<html>
<body>
<h1>Hi!</h1>
</body>
</html>
"
  cat(textString, file = "output/hi.txt")
  cat(textString, file = "output/hi.htm")
  cat(textString, file = "output/hi.html")

}

# ===== beakr pipeline =========================================================

library(beakr)

# beakr pipeline
newBeakr() %>%

  # Respond to GET requests at the "/hi" route
  httpGET(path = "/hi", function(req, res, err) {
    print("Hello, World!")
  }) %>%

  # Respond to GET requests at the "/bye" route
  httpGET(path = "/bye", function(req, res, err) {
    print("Farewell, my friends.")
  }) %>%

  # Host the directory of static files
  serveStaticFiles() %>%

  # Start the server on port 25118
  listen(host = "127.0.0.1", port = 25118)


# * http://localhost:25118/output/hi.txt  -- works
# * http://localhost:25118/output/hi.htm  -- FAILS: returns "3c"
# * http://localhost:25118/output/hi.html -- FAILS: returns "3c"

submit plumber README.md pull request

This task is a good way to practice submitting a PR (GitHub Pull Request) to another open source project.

The plumber package README.md file ends with:

Related Projects

  • OpenCPU - A server designed for hosting R APIs with an eye towards scientific research.
  • jug - (development discontinued) an R package similar to Plumber but uses a more programmatic approach to constructing the API.

You should read up on how to make a contribution, update the wording in the README.md file to replace "jug - (development discontinued) " with "beakr - " and submit a pull request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.