Package {peeky}


Title: Download and Extract 'shinylive' Applications
Version: 0.1.0
Description: Peek into published 'shinylive' applications by retrieving their source code. Supports downloading and extracting 'shiny' application source from 'quarto' documents and standalone 'shinylive' applications.
URL: https://r-pkg.thecoatlessprofessor.com/peeky/, https://github.com/coatless-rpkg/peeky
BugReports: https://github.com/coatless-rpkg/peeky/issues
License: AGPL (≥ 3)
Imports: jsonlite, httr, rvest, fs, cli
Suggests: knitr, rmarkdown, quarto, withr, testthat (≥ 3.0.0)
Encoding: UTF-8
VignetteBuilder: quarto
Config/testthat/edition: 3
Config/roxygen2/version: 8.0.0
NeedsCompilation: no
Packaged: 2026-06-26 21:10:04 UTC; ronin
Author: James Joseph Balamuta [aut, cre]
Maintainer: James Joseph Balamuta <james.balamuta@gmail.com>
Depends: R (≥ 4.1.0)
Repository: CRAN
Date/Publication: 2026-07-02 18:40:08 UTC

peeky: Download and Extract 'shinylive' Applications

Description

Peek into published 'shinylive' applications by retrieving their source code. Supports downloading and extracting 'shiny' application source from 'quarto' documents and standalone 'shinylive' applications.

Author(s)

Maintainer: James Joseph Balamuta james.balamuta@gmail.com

Authors:

See Also

Useful links:


Create a quarto_shinylive_apps class object

Description

Create a quarto_shinylive_apps class object

Usage

create_quarto_shinylive_apps(apps, output_format, output_path)

Arguments

apps

List of parsed apps

output_format

The format used ("app-dir" or "quarto")

output_path

Path where apps were written

Value

Object of class "quarto_shinylive_apps"


Create a standalone_shinylive_app class object

Description

Create a standalone_shinylive_app class object

Usage

create_standalone_shinylive_app(app_data, output_dir, url)

Arguments

app_data

Data of the app

output_dir

Path where app is written

url

The location of where the app was downloaded from

Value

Object of class "standalone_shinylive_app"


Find and Validate Shinylive app.json

Description

Attempts to locate and validate a Shinylive app.json file from a given base URL. The function tries multiple possible paths and validates both the HTTP response and JSON structure.

Usage

find_shinylive_app_json(base_url)

Arguments

base_url

Character string. The base URL to search for app.json.

Details

The function performs the following steps:

  1. Generates three possible paths to check:

    • The base URL as provided

    • base URL + '"/app.json"“

    • Parent directory + "/app.json"

  2. For each path:

    • Attempts an HTTP GET request

    • Verifies the content type is JSON

    • Parses and validates the JSON structure

    • Returns immediately if valid app.json is found

Value

A list with three components:


Find Shinylive Code Blocks in Quarto HTML

Description

Parses HTML content to extract and process Shinylive code blocks for both R and Python applications. This function identifies code blocks with class 'shinylive-r' or 'shinylive-python' and processes their content into structured application data.

Usage

find_shinylive_code(html)

Arguments

html

Character string containing HTML content. The HTML should contain code blocks with class 'shinylive-r' or 'shinylive-python' to be processed.

Details

The function performs the following steps:

  1. Parses the HTML content using rvest

  2. Extracts code blocks with classes 'shinylive-r' or 'shinylive-python'

  3. For each code block:

    • Determines the engine type from the 'data-engine' attribute

    • Extracts the code text content

    • Parses the code block structure using parse_code_block()

Code blocks should follow the Shinylive format with optional YAML-style options (prefixed with '#|') and file markers (prefixed with '## file:').

Value

A list of parsed Shinylive applications. Each list element contains:

See Also

parse_code_block


Calculate number of digits needed for padding

Description

Calculate number of digits needed for padding

Usage

padding_width(n)

Arguments

n

Number to determine digits for

Value

Number of digits needed


Parse a Single Shinylive Code Block

Description

Parses the content of a Shinylive code block, extracting YAML-style options, file definitions, and content. Handles both single-file and multi-file applications for R and Python.

Usage

parse_code_block(code_text, engine)

Arguments

code_text

Character string. The raw text content of a Shinylive code block, which may contain YAML-style options, file markers, and file content.

engine

Character string. The type of Shinylive application, either "r" or "python". Determines default file extension when no explicit file is specified.

Value

A list with three components:

Code Block Structure

The code block can contain several types of lines:

For single-file applications with no explicit file marker, the content is automatically placed in:

See Also


Parse YAML-style Options from Shinylive Code Blocks

Description

Parses YAML-style configuration options from Shinylive code block headers. These options appear as lines prefixed with '#|' and follow a simplified YAML-like syntax for key-value pairs.

Usage

parse_yaml_options(yaml_lines)

Arguments

yaml_lines

Character vector. Each element should be a line containing a YAML-style option in the format '#| key: value'. The '#|' prefix will be stripped during processing.

Details

The function handles several value types:

Lines that don't contain a colon (':') are ignored.

Value

A named list of parsed options where:

See Also

parse_code_block


Extract Shinylive Applications from Quarto Documents

Description

Downloads a Quarto document and extracts all embedded Shinylive applications. Applications can be extracted either as separate directories (for individual use) or combined into a new Quarto document (for documentation). The function handles both R and Python Shinylive applications.

Usage

peek_quarto_shinylive_app(
  url,
  output_format = c("app-dir", "quarto"),
  output_path
)

Arguments

url

Character string. URL of the Quarto document containing Shinylive applications. The document should contain code blocks with class 'shinylive-r' or 'shinylive-python'.

output_format

Character string. Determines how the applications should be extracted. Must be one of:

  • "app-dir": Creates separate directories for each application

  • "quarto": Combines all applications into a single Quarto document

output_path

Character string. Where to write the extracted applications. A relative path is resolved against the current working directory; an absolute path is used as-is.

  • For "app-dir": a directory that will hold the extracted applications

  • For "quarto": the path of the .qmd file to create

Value

An object of class "shinylive_commands" that provides:

Output Formats

The two output formats serve different purposes:

Error Handling

The function will error with informative messages if:

See Also

Examples


# Extract as separate application directories under a temporary directory
result <- peek_quarto_shinylive_app(
  "https://quarto-ext.github.io/shinylive",
  output_format = "app-dir",
  output_path = file.path(tempdir(), "quarto_apps")
)

# Combine into a new Quarto document
result <- peek_quarto_shinylive_app(
  "https://quarto-ext.github.io/shinylive",
  output_format = "quarto",
  output_path = file.path(tempdir(), "my_apps.qmd")
)

# Print will show instructions for running the apps
print(result)


Download and Extract Shinylive Applications from URLs

Description

Downloads and extracts Shinylive applications from various URL sources. The function can handle both standalone Shinylive applications and Quarto documents containing embedded Shinylive applications. It automatically detects the application type and extracts the necessary files.

Usage

peek_shinylive_app(url, output_dir)

Arguments

url

Character string. URL pointing to one of:

  • A standalone Shinylive application (containing app.json)

  • A directory containing app.json

  • A Quarto document with embedded Shinylive applications

output_dir

Character string. Directory where the application files should be extracted. A relative path is created under the current working directory; an absolute path is used as-is. The directory will be created if it doesn't exist.

Details

The function follows these steps:

  1. Downloads and analyzes the content at the provided URL

  2. Determines if the content is a Quarto document or standalone application

  3. For Quarto documents:

    • Extracts all embedded Shinylive applications

    • Creates separate directories for each application

  4. For standalone applications:

    • Locates and validates the app.json file

    • Extracts all application files to the specified directory

Value

An object containing the extracted application information:

Both object types implement custom print methods that display:

URL Resolution

The function attempts several strategies to find app.json:

Error Handling

The function will error with informative messages if:

See Also

Examples


# Write the extracted files to the session's temporary directory
url <- "https://tutorials.thecoatlessprofessor.com/convert-shiny-app-r-shinylive/"
app <- peek_shinylive_app(url, output_dir = file.path(tempdir(), "my_extracted_app"))

# Download from a Quarto document
apps <- peek_shinylive_app(
  "https://quarto-ext.github.io/shinylive/",
  output_dir = file.path(tempdir(), "my_extracted_apps")
)


Download and Extract a Standalone Shinylive Application

Description

Downloads and extracts a standalone Shinylive application from a URL. The function locates the application's app.json file, validates its structure, and extracts all application files to a local directory. Works with both R and Python Shinylive applications.

Usage

peek_standalone_shinylive_app(url, output_dir)

Arguments

url

Character string. URL pointing to either:

  • A Shinylive app.json file directly

  • A directory containing app.json

The function will automatically append "app.json" to directory URLs.

output_dir

Character string. Directory where the application files should be extracted. A relative path is created under the current working directory; an absolute path is used as-is. Will be created if it doesn't exist. If the directory already exists, files may be overwritten.

Value

An object of class "standalone_shinylive_app" containing:

The object has a custom print method that displays:

File Structure

A valid Shinylive application should have an app.json file containing:

Error Handling

The function will error with informative messages if:

See Also

Examples


# Download from a direct app.json URL into a temporary directory
app <- peek_standalone_shinylive_app(
  "https://tutorials.thecoatlessprofessor.com/convert-shiny-app-r-shinylive/app.json",
  output_dir = file.path(tempdir(), "standalone_app")
)

# Download from a directory URL (app.json will be appended)
app <- peek_standalone_shinylive_app(
  "https://tutorials.thecoatlessprofessor.com/convert-shiny-app-r-shinylive/",
  output_dir = file.path(tempdir(), "my_local_app")
)

# Print shows how to run the application
print(app)


Print method for quarto_shinylive_apps objects

Description

Print method for quarto_shinylive_apps objects

Usage

## S3 method for class 'quarto_shinylive_apps'
print(x, ...)

Arguments

x

Object of class "quarto_shinylive_apps"

...

Additional arguments passed to print

Value

Invisibly returns the original object of class quarto_shinylive_apps. Primarily called for its side effect of displaying formatted information about:


Print method for standalone_shinylive_app objects

Description

Print method for standalone_shinylive_app objects

Usage

## S3 method for class 'standalone_shinylive_app'
print(x, ...)

Arguments

x

Object of class "standalone_shinylive_app"

...

Additional arguments passed to print

Value

Invisibly returns the original object of class standalone_shinylive_app. Primarily called for its side effect of displaying formatted information about:


Validate Shinylive app.json Structure

Description

Validates that a parsed app.json structure meets the requirements for a Shinylive application. Checks for proper list structure, required fields, and non-empty content. Provides detailed error messages when validation fails.

Usage

validate_app_json(json_data)

Arguments

json_data

List. Parsed JSON data from an app.json file. Should be a list where each element represents a file and contains:

  • name: Character string of the file name

  • content: Character string of the file content

  • type: Character string indicating the file type

Value

Logical TRUE if validation passes. If validation fails, throws an error with detailed information about the validation failure using cli_abort().

Validation Rules

The function checks these requirements:

  1. json_data must be a list

  2. json_data must contain at least one element

  3. Each element must be a list (representing a file)

  4. Each file list must contain all required fields:

    • name

    • content

    • type

Error Messages

The function provides detailed error messages for these cases:

Expected JSON Structure

The expected JSON structure is an array of objects, where each object represents a file in the application.

[
  {
    "name": "app.R",
    "content": "library(shiny)\n...",
    "type": "text"
  },
  {
    "name": "data/example.csv",
    "content": "x,y\n1,2\n...",
    "type": "text"
  }
]

See Also


Write Multiple Shinylive Applications to Separate Directories

Description

Takes a list of parsed Shinylive applications and writes each to its own numbered subdirectory. Creates consistently numbered directories with proper padding (e.g., app_01, app_02) and preserves all application files and metadata.

Usage

write_apps_to_dirs(apps, base_dir)

Arguments

apps

List of parsed Shinylive applications. Each application should contain:

  • engine: Character string identifying the app type ("r" or "python")

  • options: List of YAML-style options from the original code block

  • files: Named list of file definitions, each containing:

    • name: Character string of the file name

    • content: Character string of the file content

    • type: Character string indicating the file type

base_dir

Character string. Base directory where application subdirectories should be created. Will be created if it doesn't exist.

Details

The function performs these steps:

  1. Creates the base directory if needed

  2. Calculates proper padding for subdirectory numbers

  3. For each application:

    • Creates a padded, numbered subdirectory (e.g., app_01, app_02)

    • Writes all application files, preserving directory structure

    • Creates a metadata JSON file with engine and options info

Value

No return value, called for its side effect of writing one application subdirectory per app (plus a metadata file) under base_dir.

Directory Structure

Creates a directory structure like:

base_dir/
|-- app_01/
|   |-- app.R
|   |-- data/
|   |   `-- example.csv
|   `-- shinylive_metadata.json
|-- app_02/
|   |-- app.py
|   `-- shinylive_metadata.json
`-- ...

Metadata File

Each directory includes a shinylive_metadata.json file containing:

{
  "engine": "r",
  "options": {
    "viewerHeight": 500,
    "...": "..."
  }
}

See Also

Examples

# Example apps list structure
apps <- list(
  list(
    engine = "r",
    options = list(viewerHeight = 500),
    files = list(
      "app.R" = list(
        name = "app.R",
        content = "library(shiny)\n...",
        type = "text"
      )
    )
  ),
  list(
    engine = "python",
    options = list(),
    files = list(
      "app.py" = list(
        name = "app.py",
        content = "from shiny import App\n...",
        type = "text"
      )
    )
  )
)

write_apps_to_dirs(apps, file.path(tempdir(), "extracted_apps"))

Write Shinylive Applications to a Quarto Document

Description

Converts a list of parsed Shinylive applications into a single Quarto document. Creates a properly formatted .qmd file with YAML frontmatter, organized sections for each application, and correctly formatted code blocks with all necessary markers and options.

Usage

write_apps_to_quarto(apps, qmd_path)

Arguments

apps

List of parsed Shinylive applications. Each application should contain:

  • engine: Character string identifying the app type ("r" or "python")

  • options: List of YAML-style options from the original code block

  • files: Named list of file definitions, each containing:

    • name: Character string of the file name

    • content: Character string of the file content

    • type: Character string indicating the file type

qmd_path

Character string. Path where the Quarto document should be written. Should end with .qmd extension. Parent directory will be created if it doesn't exist.

Details

The function performs these steps:

  1. Creates YAML frontmatter with required Quarto settings

  2. For each application:

    • Adds a section header with application number

    • Creates a code block with appropriate engine (shinylive-r/shinylive-python)

    • Converts and adds all application options

    • Adds file markers and content for each file

    • Properly closes the code block

  3. Writes the complete document to the specified path

Value

No return value, called for its side effect of writing a Quarto document to qmd_path.

Document Structure

Creates a Quarto document with this structure:

---
title: Extracted Shinylive Applications
filters:
  - shinylive
---

# Shinylive Applications

## Application 1

```{shinylive-r}
#| viewerHeight: 500
## file: app.R
## type: text
library(shiny)
...
```

## Application 2
...

Option Formatting

Options are converted to YAML format based on their type:

See Also

Examples

# Example apps list structure
apps <- list(
  list(
    engine = "r",
    options = list(
      viewerHeight = 500,
      fullWidth = TRUE
    ),
    files = list(
      "app.R" = list(
        name = "app.R",
        content = "library(shiny)\n...",
        type = "text"
      )
    )
  )
)

write_apps_to_quarto(apps, file.path(tempdir(), "applications.qmd"))

Write File Content in a Shinylive App to Disk

Description

Writes file content extracted from Shinylive applications to disk, handling both text and binary content appropriately. Creates any necessary parent directories and ensures proper encoding of content. For binary files, automatically decodes the base64-encoded content before writing.

Usage

write_file_content(content, file_path, type = "text")

Arguments

content

Character string containing the file content. For binary files, this should be base64-encoded content. For text files, this should be the raw text content.

file_path

Character string specifying the path where the file should be written. Parent directories will be created if they don't exist.

type

Character string specifying the file type, either "text" (default) or "binary". Binary files are assumed to be base64 encoded, as this is the standard format for binary content in Shinylive applications.

Details

The function handles two types of content:

Parent directories in the file path are automatically created if they don't exist using fs::dir_create() with recurse = TRUE.

Value

Invisible NULL, called for its side effect of writing a file to disk.

Examples

# Write a text file into a temporary directory
write_file_content(
  content = "library(shiny)\n\nui <- fluidPage()",
  file_path = file.path(tempdir(), "app", "app.R"),
  type = "text"
)

# Write a base64-encoded image
b64img <- paste0(
  "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA",
  "DUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
)
write_file_content(b64img, file.path(tempdir(), "test.png"), type = "binary")

Write Standalone Shinylive Application Files from JSON Data

Description

Extracts files from parsed Shinylive app.json data and writes them to a specified directory. Creates a standalone application object containing metadata and commands for running the application.

Usage

write_standalone_shinylive_app(json_data, source_url, output_dir)

Arguments

json_data

List. Parsed JSON data from a Shinylive app.json file. Each element should be a list containing:

  • name: Character string of the file name

  • content: Character string of the file content

  • type: Character string indicating the file type

source_url

Character string. The original URL from which the app.json was downloaded. Used for reference and provenance tracking in the returned object.

output_dir

Character string. Directory where application files should be extracted. A relative path is created under the current working directory; an absolute path is used as-is. Will be created if it doesn't exist. Existing files in this directory may be overwritten.

Details

The function performs these steps:

  1. Creates the output directory if it doesn't exist

  2. Iterates through each file in the JSON data

  3. Writes each file to the output directory, preserving names

  4. Creates a standalone application object with metadata

File paths are created relative to the output directory. Parent directories in file paths will be created as needed.

Value

An object of class "standalone_shinylive_app" containing:

File Structure

Expected JSON data structure:

[
  {
    "name": "app.R",
    "content": "library(shiny)\n...",
    "type": "text"
  },
  {
    "name": "data/example.csv",
    "content": "x,y\n1,2\n...",
    "type": "text"
  }
]

See Also

Examples

# Example JSON data structure
json_data <- list(
  list(
    name = "app.R",
    content = "library(shiny)\nui <- fluidPage()\n...",
    type = "text"
  ),
  list(
    name = "data.csv",
    content = "col1,col2\n1,2\n3,4",
    type = "text"
  )
)

app <- write_standalone_shinylive_app(
  json_data,
  "https://example.com/app.json",
  file.path(tempdir(), "my_app")
)

mirror server hosted at Truenetwork, Russian Federation.