Skip to content

PawanRamaMali/shinypayload

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

shinypayload shinypayload logo

CRAN status R-CMD-check test-coverage pkgdown Lifecycle: experimental License: MIT GitHub stars GitHub issues GitHub last commit Downloads

Bring data into Shiny on the same port πŸš€

Seamlessly integrate POST requests and query parameters into your existing Shiny apps as reactive values. Zero configuration - works with your current UI on the same port.

✨ Key Features

  • πŸ”Œ Same-port integration - No need for separate servers or ports
  • πŸ“‘ RESTful API endpoints - Accept POST requests alongside your Shiny UI
  • πŸ”„ Reactive data streams - POST data automatically becomes reactive values
  • πŸ›‘οΈ Built-in authentication - Token-based security for your endpoints
  • πŸ“± Multiple data formats - JSON, form data, query parameters
  • 🌐 Cross-session sharing - Data shared across all connected clients
  • 🚦 Production ready - Comprehensive testing and CRAN-quality code

πŸš€ Quick Start

Installation

# Install from CRAN
install.packages("shinypayload")

# Install development version from GitHub
remotes::install_github("PawanRamaMali/shinypayload")

# For local development
devtools::load_all()

Basic Example

library(shiny)
library(shinypayload)

# Your regular UI - no changes needed!
base_ui <- fluidPage(
  titlePanel("πŸš€ shinypayload Demo"),
  
  fluidRow(
    column(6,
      h4("πŸ“Š Live Data"),
      verbatimTextOutput("live_data")
    ),
    column(6,
      h4("πŸ”— URL Parameters"),
      verbatimTextOutput("url_params")
    )
  ),
  
  hr(),
  h4("πŸ“‘ POST Endpoint"),
  verbatimTextOutput("endpoint_info")
)

# Wrap your UI to handle POST requests
ui <- payload_ui(
  base_ui,
  path = "/api/data",
  token = Sys.getenv("API_TOKEN", "demo-token")
)

server <- function(input, output, session) {
  # Get URL parameters
  output$url_params <- renderPrint({
    params <- params_get(session)
    if (length(params) > 0) params else "No URL parameters"
  })
  
  # Show endpoint URL
  output$endpoint_info <- renderText({
    url <- payload_endpoint_url(session, "/api/data")
    paste("Send POST requests to:", url, "?token=demo-token")
  })
  
  # React to incoming POST data
  live_data <- payload_last("/api/data", session, intervalMillis = 200)
  
  output$live_data <- renderPrint({
    data <- live_data()
    if (is.null(data)) {
      "Waiting for data... πŸ“‘"
    } else {
      list(
        timestamp = data$meta$timestamp,
        payload = data$payload,
        source = data$meta$remote_addr
      )
    }
  })
}

# IMPORTANT: Use uiPattern = ".*" for POST routing
shinyApp(ui, server, uiPattern = ".*")

Send Data to Your App

# Send JSON data
curl -X POST "http://localhost:3838/api/data?token=demo-token" \\
  -H "Content-Type: application/json" \\
  -d '{"sensor": "temperature", "value": 23.5, "unit": "celsius"}'

# Send form data  
curl -X POST "http://localhost:3838/api/data?token=demo-token" \\
  -d "name=sensor01&status=active&reading=42"

# Response: {"ok": true}

πŸ“– Documentation

Core Functions

Function Purpose Example
payload_ui() Wrap UI to handle POST requests payload_ui(my_ui, "/api", "token")
payload_last() Get reactive with latest POST data data <- payload_last("/api", session)
params_get() Extract URL query parameters params <- params_get(session)
payload_endpoint_url() Get full endpoint URL url <- payload_endpoint_url(session, "/api")

Authentication Methods

# Query parameter (recommended)
POST /api/data?token=your-secret-token

# HTTP Headers
POST /api/data
X-Ingress-Token: your-secret-token
# OR
Authorization: your-secret-token

Supported Content Types

  • application/json - Parsed with jsonlite::fromJSON()
  • application/x-www-form-urlencoded - Parsed with shiny::parseQueryString()
  • Fallback: Attempts JSON parsing, returns raw text if failed

πŸ’‘ Use Cases

πŸ“Š Real-time Dashboards

  • IoT sensor data streaming
  • Live monitoring systems
  • Real-time analytics

πŸ€– API Integration

  • Webhook receivers
  • External service integration
  • Microservice communication

πŸ“± Mobile/Web Apps

  • React/Vue.js β†’ Shiny data flow
  • Progressive web apps
  • Cross-platform integration

πŸ”„ ETL Pipelines

  • Data ingestion endpoints
  • Batch processing triggers
  • Workflow automation

πŸ“‚ Complete Examples

Explore our comprehensive examples in inst/examples/:

Each example includes ready-to-run code and curl commands for testing.

πŸ›‘οΈ Security Best Practices

  1. Always use tokens in production

    ui <- payload_ui(base_ui, "/api", Sys.getenv("API_SECRET"))
  2. Validate and sanitize input data

    observeEvent(payload_last("/api", session), {
      data <- payload_last("/api", session)()
      if (!is.null(data)) {
        # Validate required fields
        if (is.null(data$payload$user_id)) return()
        # Sanitize inputs before use
        clean_data <- DBI::dbQuoteString(pool, data$payload$message)
      }
    })
  3. Use HTTPS in production

  4. Implement rate limiting if needed

  5. Monitor and log API usage

πŸ”§ Advanced Configuration

Multiple Endpoints

# Handle different data types on different paths
ui <- payload_ui(base_ui, "/sensors", "sensor-token")

server <- function(input, output, session) {
  # Different reactives for different endpoints
  sensor_data <- payload_last("/sensors", session)
  user_data <- payload_last("/users", session)
  
  # Process accordingly...
}

Custom Polling Intervals

# High-frequency updates (100ms)
fast_data <- payload_last("/live", session, intervalMillis = 100)

# Low-frequency updates (5 seconds) 
slow_data <- payload_last("/batch", session, intervalMillis = 5000)

🀝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development Setup

# Clone and install dependencies
git clone https://github.com/PawanRamaMali/shinypayload.git
cd shinypayload

# Install in development mode
devtools::load_all()

# Run tests
devtools::test()

# Check package
devtools::check()

πŸ“Š Package Status

  • βœ… 132 tests with comprehensive coverage
  • βœ… Cross-platform compatibility (Windows, macOS, Linux)
  • βœ… Multiple R versions supported (R β‰₯ 4.1)
  • βœ… CRAN ready - passes all checks
  • βœ… Production tested - used in real applications

πŸ“‹ Requirements

  • R β‰₯ 4.1
  • shiny β‰₯ 1.7.4
  • jsonlite (any version)

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built on the amazing Shiny framework
  • Inspired by the need for seamless data integration in web applications
  • Thanks to the R community for feedback and contributions

πŸ“ž Support


Made with ❀️ for the R and Shiny community

⭐ Star this repo β€’ 🍴 Fork it β€’ πŸ“’ Share it

About

Bring data into Shiny on the same port

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE
MIT
LICENSE.md

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages