Giter VIP home page Giter VIP logo

ambiorix's People

Contributors

benjaminschwetz avatar gueyenono avatar johncoene avatar kennedymwavu avatar merlinoa avatar ryanbrunousdc 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ambiorix's Issues

Tailwind

Using tailwind with ambiorix should be straightforward but we may want functionalities to make it even easier.

Serialisers

Add serialisers, png, json, XML, htmlwidgets, etc.

Add template

Add a convenience function to create templates

Trying to run a post example

Two changes needed to make this work with the master version.

  1. I updated your post example at https://ambiorix.john-coene.com/#/examples/post should be to:
# app.R

library(ambiorix)
library(htmltools)
library(mime)

app <- Ambiorix$new()

app$get("/", function(req, res){

   # form
   # sends to /submit
  form <- tagList(
    tags$form(
      action = "/submit", enctype = "multipart/form-data", method = "POST",
      p(
        tags$label('for' = "first_name", "First Name"),
        tags$input(type = "text", name = "first_name")
      ),
      tags$input(type = "submit")
    )
  )

  res$send(form)
})

app$post("/submit", function(req, res){
  body <- parse_multipart(req$body)
  res$send(h1("Your name is", body$first_name))
})

app$start()
  1. And modified the master Dockerfile include the mime package install after htmltools:

RUN R -e "install.packages('mime')"

Then the post example works with my docker test server.

Nice work!
Stephen

On Close

Allow passing function on server close.

parsers

Parsers to parse results: json, xml, multipart, etc.

check_installed missing a !

Hi,

I was trying to send an htmlwidget using res$htmlwidget(), but the app kept insisting that the package is not installed. It seems like check_installed() logic is flipped, i.e. it is throwing an error when the package is installed.

Parse HEADERS

Parse headers on the request to easily fetch them.

Minify

We should minify the HTML, CSS, etc.

Support a res$send variant that doesn't convert data to character?

Neat package!

I used it to conjure up a vector tile server with very little code, but I'm having a problem, which I think is because my tile data (raw vector) is getting transformed to text by the as.character() in res$send(). There doesn't seem to a res$send variant that will let me send my data as binary (Content-Type: application/x-protobuf).

Would you consider adding this? Or accepting a PR?

Send file

Add send_file: template but without rendering

Issue with parsing request body

Hi John, good start on the abiorix package! I checked it out and run into 2 issues when parsing the request body.

(1) 1st thing is easy: parse_json is not exported, so add #' @export to R/parser.R.

(2) But even when I used ::: still got ERROR: attempt to apply non-function. Here is what I had for my Hello World example:

library(ambiorix)

app <- Ambiorix$new()

handle <- function(req) {
  body <- ambiorix:::parse_json(req)
  paste0('Hello ', body, '!')
}

app$post('/', function(req, res){
  res$json(handle(req))
})

app$start()

Maybe it is a content type issue, but something is definitely not right here. Thanks!

Small typo in code

A minimal hello world example of {ambiorix} gives an error log

app <- ambiorix::Ambiorix$new()

app$get("/", \(req, res) {
    res$send("Hello World!")
})

app$start()
✔ 07-01-2024 13:14:16 Listening on http://localhost:31739
Error in inerits(x, "error") : could not find function "inerits"
> ℹ 07-01-2024 13:14:16 GET on /
✖ 07-01-2024 13:14:16 GET on /favicon.ico - Not found

The line below should be inherits instead of inherits.

if(inerits(x, "error"))

Add a "strengths and weaknesses" section?

Hello @JohnCoene, I think that one thing that is missing in your documentation is a section about comparing strengths and weaknesses of ambiorix and shiny. As someone who first discovered R, then shiny, and then the world of web development (probably as several shiny users), I don't know what express.js is and I don't know why it is useful.

As you say in this section:

Designing applications will, in all likelihood, always be faster with Shiny.

As a reader, when I see this, my reaction is more or less: then why should I use ambiorix? I know that you show some examples in the docs, but the syntax is very different from shiny and it seems quite complicated. I think there should be a section where you show/explain common shiny problems, and how ambiorix makes it easier to solve them. Also, as a side question, is ambiorix a lot different than brochure?

I don't want this to sound as a criticism, I'm just trying to figure out if I should learn more about express.js and ambiorix. Thanks again for all this open source collection of tools! (PS: love the docs and the pictures used)

Router

Add router for nested path

Content-Type header is overridden by send defaults (doco issue?)

I found this example in the doco for response headers:

app$get("/hello", \(req, res){
  res$header("Content-Type", "something")
  res$send("Using {ambiorix}!")
})

The problem is that send() has a default for the headers arg: content_html() which will replace the custom Content-Type header something with text/html.

Deprecate add_template

Templates differ, see generator: should be deprecated and moved to ambiorix.generator

Templates worked for me after one change...

Before import("views"), I needed to add a working directory at the root of template app:

# app.R is in /myapps/template01
setwd("/myapps/template01")

Then it worked. Without this addition, I observed this error:

Error: [ENOENT] Failed to search directory '//views': no such file or directory

Perhaps I overlooked a more elegant solution?

Best,
Stephen

Template R

Support R templates in response family (htmltools tags)

Log

Allow app creating logs

Port option

Port option à la shiny to avoid running the app on a different port every time (dev iteration)

Tests

Add tests.

Need input/ideas on how to do this best for web servers, .e.g.: mock requests, etc.

Next

Allow using next to use next method

Non-blocking Database Queries within app$get()

Project:
The goal is an API which queries a database. Results set length varies a lot and so does the response time. In order to avoid blocking of fast queries by slow ones the API should by async.

Problem:
future does not allow for external pointers (such as DB connections, pool connections, etc.), thus I had to open a new DB connection (within future) for every request which slows down response time significantly

I am looking for a solution based on this example with a non-blocking query_db() functionality within the future.

Any help would be greatly appreciated!

library(future)
library(ambiorix)

plan(multisession)

app <- Ambiorix$new()

app$get("/async", function(req, res){
  future({
    dat <- query_db()
    res$send(dat)
  })
})
app$start()

Future

Handle future for asynchronous requests

Error handling not working

Description

Ambiorix's error handling does not seem to work. It always sends the actual error message to the client.

Reprex

library(ambiorix)

app <- Ambiorix$new()

app$get("/", \(req, res) {
  res$send("Hello, World!")
})

# simulate error (object 'Pikachu' is not defined)
app$get("/whoami", \(req, res) {
  print(Pikachu)
})

# `not_found` works as expected✅
app$not_found <- \(req, res) {
  res$status <- 404L
  res$send("Oops, the page you're looking for was not found!")
}

# `error` does NOT work as expected❌
# Instead of sending this to the client, it sends the actual
# error message
app$error <- \(req, res) {
  res$status <- 500L
  res$send("Uhhmmm... Looks like there's an error from our side :(")
}

app$start(port = 8000L, open = FALSE)

image

Expectation

When an error occurs, it should send the customized message instead of the actual error message. For purposes of security.

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.