{"id":27058411,"url":"https://github.com/gonzalo123/r","last_synced_at":"2026-04-25T12:36:46.678Z","repository":{"id":286270161,"uuid":"960913529","full_name":"gonzalo123/R","owner":"gonzalo123","description":"Real-time Data Visualization with R Shiny and External APIs","archived":false,"fork":false,"pushed_at":"2025-04-05T10:49:21.000Z","size":117,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T19:16:05.606Z","etag":null,"topics":["api","python","r","rscript"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gonzalo123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-04-05T10:43:49.000Z","updated_at":"2025-04-05T10:49:25.000Z","dependencies_parsed_at":"2025-04-05T11:41:18.513Z","dependency_job_id":null,"html_url":"https://github.com/gonzalo123/R","commit_stats":null,"previous_names":["gonzalo123/r"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2FR","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2FR/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2FR/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2FR/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gonzalo123","download_url":"https://codeload.github.com/gonzalo123/R/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248094988,"owners_count":21046770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","python","r","rscript"],"created_at":"2025-04-05T12:15:12.046Z","updated_at":"2026-04-25T12:36:46.627Z","avatar_url":"https://github.com/gonzalo123.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Real-time Data Visualization with R Shiny and External APIs\n\nToday we will create a simple R Shiny frontend application that fetches real-time data from an external API. First we\nhave a backend API that provides a simple JSON response protected by a bearer token.\n\n```python\nimport random\nfrom functools import wraps\n\nfrom flask import Flask, jsonify, request\n\napp = Flask(__name__)\n\nVALID_TOKEN = \"api-secret-token\"\n\n\ndef token_required(valid_token=VALID_TOKEN):\n    def decorator(f):\n        @wraps(f)\n        def decorated(*args, **kwargs):\n            token = None\n            auth_header = request.headers.get('Authorization')\n            if auth_header and auth_header.startswith('Bearer '):\n                token = auth_header.split(' ')[1]\n\n            if not token or token != valid_token:\n                return jsonify({'message': 'Not valid token'}), 401\n\n            return f(*args, **kwargs)\n\n        return decorated\n\n    return decorator\n\n\ndef generate_phone_number():\n    area_code = random.randint(200, 999)\n    prefix = random.randint(100, 999)\n    line = random.randint(1000, 9999)\n    return f\"+1 {area_code}-{prefix}-{line}\"\n\n\n@app.get('/data')\n@token_required(valid_token=VALID_TOKEN)\ndef get_data():\n    return jsonify([\n        {\"phone\": generate_phone_number(), \"name\": \"Juan Pérez\", \"email\": \"juan@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"María García\", \"email\": \"maria@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Carlos López\", \"email\": \"carlos@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Ana Martínez\", \"email\": \"ana@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Pablo Sánchez\", \"email\": \"pablo@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Laura Rodríguez\", \"email\": \"laura@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Diego Fernández\", \"email\": \"diego@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Carmen Gómez\", \"email\": \"carmen@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Javier Díaz\", \"email\": \"javier@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Sofía Ruiz\", \"email\": \"sofia@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Miguel Álvarez\", \"email\": \"miguel@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Lucía Jiménez\", \"email\": \"lucia@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Alejandro Moreno\", \"email\": \"alejandro@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Elena Muñoz\", \"email\": \"elena@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"David Alonso\", \"email\": \"david@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Natalia Torres\", \"email\": \"natalia@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Roberto Gutiérrez\", \"email\": \"roberto@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Cristina Navarro\", \"email\": \"cristina@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Antonio Ramos\", \"email\": \"antonio@example.com\"},\n        {\"phone\": generate_phone_number(), \"name\": \"Isabel Ortega\", \"email\": \"isabel@example.com\"}\n    ])\n```\n\nThe frontend application is a simple R Shiny app that fetches data from the API and displays it in a table. The app also\nincludes a button to refresh the data.\n\nWe'll use renv to manage the R package dependencies. To set up the environment, run the following commands in your R\nconsole:\n\n```R\ninstall.packages(\"renv\")\nrenv::init()\n```\n\nThen, install the required packages:\n\n```R\ninstall.packages(\"shiny\")\ninstall.packages(\"readxl\")\ninstall.packages(\"dplyr\")\ninstall.packages(\"qcc\")\ninstall.packages(\"ggplot2\")\ninstall.packages(\"shinyWidgets\")\ninstall.packages(\"dotenv\")\ninstall.packages(\"DT\")\ninstall.packages(\"httr\")\ninstall.packages(\"jsonlite\")\n\nrenv::snapshot()\n```\n\nThat's the main.R file.\n\n```R\nlibrary(shiny)\n\nsource(\"api_client.R\")\n\nargs \u003c- commandArgs(trailingOnly = TRUE)\nport \u003c- if (length(args) \u003e= 1) as.numeric(args[1]) else 3838\nhost \u003c- if (length(args) \u003e= 2) args[2] else \"0.0.0.0\"\nlaunch_browser \u003c- if (length(args) \u003e= 3) as.logical(args[3]) else TRUE\n\nrunApp(\"app.R\", port = port, host = host, launch.browser = launch_browser)\n```\n\nAnd the shiny app is in the app.R file.\n\n```R\nlibrary(shiny)\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(shinyWidgets)\nlibrary(dotenv)\nlibrary(DT)\n\ndf \u003c- data.frame()\nload_dot_env()\n\nconfig \u003c- list(\n  api_url = Sys.getenv(\"API_URL\"),\n  api_token = Sys.getenv(\"API_KEY\")\n)\n\nui \u003c- fluidPage(\n  titlePanel(\"R api call example\"),\n\n  fluidRow(\n    column(12,\n           actionButton(\"refresh\", \"Refresh data\", icon = icon(\"refresh\"), class = \"btn-primary\")\n    )\n  ),\n\n  mainPanel(\n    DTOutput(\"table\")\n  )\n)\n\nserver \u003c- function(input, output, session) {\n  data \u003c- reactiveVal(df)\n\n  refreshData(data, config$api_url, config$api_token)\n\n  observeEvent(input$refrescar, {\n    refreshData(data, config$api_url, config$api_token)\n  })\n\n  output$table \u003c- renderDT({\n    data()\n  })\n}\n\nshinyApp(ui = ui, server = server)\n```\n\nThe `api_client.R` file contains the function to fetch data from the API.\n\n```R\nget_data \u003c- function(uri, token = NULL) {\n  library(httr)\n  library(jsonlite)\n\n  showNotification(\"Updating data...\", type = \"message\")\n\n  headers \u003c- c(`Content-Type` = \"application/json\", `Accept` = \"application/json\")\n  if (!is.null(token)) {\n    headers \u003c- c(headers, Authorization = paste(\"Bearer\", token))\n  }\n\n  response \u003c- GET(url = uri, add_headers(.headers = headers))\n\n  if (http_error(response)) {\n    stop(sprintf(\"Error en la petición: %s\", status_code(response)))\n  }\n\n  content_text \u003c- content(response, \"text\", encoding = \"UTF-8\")\n  df \u003c- fromJSON(content_text, flatten = TRUE)\n\n  if (is.list(df) \u0026\u0026 \"data\" %in% names(df)) {\n    df \u003c- df$data\n  }\n\n  if (!is.data.frame(df)) {\n    df \u003c- as.data.frame(df)\n  }\n\n  return(df)\n}\n```\n\nWe're also using dotenv to manage environment variables. Create a `.env` file in the root of your project with the following content:\n\n```dotenv\nAPI_URL=http://localhost:5000/data\nAPI_KEY=api-secret-token \n```\n\n![](doc/R_api_call_example.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo123%2Fr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgonzalo123%2Fr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo123%2Fr/lists"}