Skip to content

Commit b55a81b

Browse files
authored
feat: return a list of Content class objects from search_content() (#463)
1 parent 73ce793 commit b55a81b

File tree

4 files changed

+34
-252
lines changed

4 files changed

+34
-252
lines changed

R/content.R

Lines changed: 16 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#' Content
22
#'
3-
#' An R6 class that represents content
3+
#' An R6 class that represents content.
44
#'
55
#' @family R6 classes
66
#' @export
77
Content <- R6::R6Class(
88
"Content",
99
public = list(
10-
#' @field connect An R6 Connect object
10+
#' @field connect An R6 Connect object.
1111
connect = NULL,
12-
#' @field content The content details from Posit Connect
12+
#' @field content The content details from Posit Connect. Properties are described in [get_content()].
1313
content = NULL,
1414

1515
#' @description Initialize this content.
@@ -1504,122 +1504,7 @@ get_content_packages <- function(content) {
15041504
#' usually not what you want.
15051505
#'
15061506
#' @return
1507-
#' A list containing sub-fields:
1508-
#' * `total`: The total number of results.
1509-
#' * `results`: A list of lists representing content items on Connect.
1510-
#'
1511-
#' Each piece of content contains the following fields:
1512-
#' * `guid`: The unique identifier of this content item.
1513-
#' * `name`: A simple, URL-friendly identifier. Allows alpha-numeric
1514-
#' characters, hyphens ("-"), and underscores ("_").
1515-
#' * `title`: The title of this content.
1516-
#' * `description`: A rich description of this content
1517-
#' * `access_type`: Access type describes how this content manages its
1518-
#' viewers. It may have a value of `all`, `logged_in` or `acl`.
1519-
#' The value `all` is the most permissive; any visitor to Posit
1520-
#' Connect will be able to view this content. The value `logged_in`
1521-
#' indicates that all Posit Connect accounts may view the content. The
1522-
#' `acl` value lets specifically enumerated users and groups view the
1523-
#' content. Users configured as collaborators may always view content.
1524-
#' * `connection_timeout`: Maximum number of seconds allowed without data
1525-
#' sent or received across a client connection. A value of 0 means
1526-
#' connections will never time-out (not recommended). When null, the
1527-
#' default `Scheduler.ConnectionTimeout` is used. Applies only to content
1528-
#' types that are executed on demand.
1529-
#' * `read_timeout`: Maximum number of seconds allowed without data received
1530-
#' from a client connection. A value of 0 means a lack of client (browser)
1531-
#' interaction never causes the connection to close. When null, the default
1532-
#' `Scheduler.ReadTimeout` is used. Applies only to content types that are
1533-
#' executed on demand.
1534-
#' * `init_timeout`: The maximum number of seconds allowed for an interactive
1535-
#' application to start. Posit Connect must be able to connect
1536-
#' to a newly launched Shiny application, for example, before this threshold
1537-
#' has elapsed. When null, the default `Scheduler.InitTimeout` is
1538-
#' used. Applies only to content types that are executed on demand.
1539-
#' * `idle_timeout`: The maximum number of seconds a worker process
1540-
#' for an interactive application to remain alive after it goes idle (no
1541-
#' active connections). When null, the default `Scheduler.IdleTimeout`
1542-
#' is used. Applies only to content types that are executed on demand.
1543-
#' * `max_processes`: Specifies the total number of concurrent processes
1544-
#' allowed for a single interactive application. When null, the
1545-
#' default `Scheduler.MaxProcesses` setting is used. Applies only to
1546-
#' content types that are executed on demand.
1547-
#' * `min_processes`: Specifies the minimum number of concurrent
1548-
#' processes allowed for a single interactive application. When null, the
1549-
#' default `Scheduler.MinProcesses` is used. Applies only to content types
1550-
#' that are executed on demand.
1551-
#' * `max_conns_per_process`: Specifies the maximum number of
1552-
#' client connections allowed to an individual process. Incoming connections
1553-
#' which will exceed this limit are routed to a new process or rejected.
1554-
#' When null, the default `Scheduler.MaxConnsPerProcess` is used. Applies
1555-
#' only to content types that are executed on demand.
1556-
#' * `load_factor`: Controls how aggressively new processes are spawned.
1557-
#' When null, the default `Scheduler.LoadFactor` is used. Applies only to
1558-
#' content types that are executed on demand.
1559-
#' * `created_time`: The timestamp (RFC3339) indicating when this
1560-
#' content was created.
1561-
#' * `last_deployed_time`: The timestamp (RFC3339) indicating when
1562-
#' this content last had a successful bundle deployment performed.
1563-
#' * `bundle_id`: The identifier for the active deployment bundle.
1564-
#' Automatically assigned upon the successful deployment of that bundle.
1565-
#' * `app_mode`: The runtime model for this content. Has a value
1566-
#' of `unknown` before data is deployed to this item. Automatically assigned
1567-
#' upon the first successful bundle deployment. Allowed: `api`,
1568-
#' `jupyter-static`, `python-api`, `python-bokeh`, `python-dash`,
1569-
#' `python-streamlit`, `rmd-shiny`, `rmd-static`, `shiny`, `static`,
1570-
#' `tensorflow-saved-model`, `unknown`.
1571-
#' * `content_category`: Describes the specialization of the content
1572-
#' runtime model. Automatically assigned upon the first successful bundle
1573-
#' deployment.
1574-
#' * `parameterized`: True when R Markdown rendered content
1575-
#' allows parameter configuration. Automatically assigned upon the first
1576-
#' successful bundle deployment. Applies only to content with an app_mode
1577-
#' of rmd-static.
1578-
#' * `r_version`: The version of the R interpreter associated
1579-
#' with this content. The value null represents that an R interpreter is
1580-
#' not used by this content or that the R package environment has not been
1581-
#' successfully restored. Automatically assigned upon the successful
1582-
#' deployment of a bundle.
1583-
#' * `py_version`: The version of the Python interpreter
1584-
#' associated with this content. The value null represents that a Python
1585-
#' interpreter is not used by this content or that the Python package
1586-
#' environment has not been successfully restored. Automatically assigned
1587-
#' upon the successful deployment of a bundle.
1588-
#' * `run_as`: The UNIX user that executes this content.
1589-
#' When null, the default Applications.RunAs is used. Applies
1590-
#' only to executable content types - not static.
1591-
#' * `run_as_current_user`: Indicates if this content is allowed
1592-
#' to execute as the logged-in user when using PAM authentication.
1593-
#' Applies only to executable content types - not static.
1594-
#' * `owner_guid`: The unique identifier for the owner
1595-
#' * `content_url`: The URL associated with this content. Computed
1596-
#' from the GUID for this content.
1597-
#' * `dashboard_url`: The URL within the Connect dashboard where
1598-
#' this content can be configured. Computed from the GUID for this content.
1599-
#' * `role`: The relationship of the accessing user to this
1600-
#' content. A value of owner is returned for the content owner. editor
1601-
#' indicates a collaborator. The viewer value is given to users who are
1602-
#' permitted to view the content. A none role is returned for
1603-
#' administrators who cannot view the content but are permitted to view
1604-
#' its configuration. Computed at the time of the request.
1605-
#' * `vanity_url`: The vanity URL associated with this content item.
1606-
#' * `id`: The internal numeric identifier of this content item.
1607-
#' * `tags`: Tags associated with this content item. Each entry is a list
1608-
#' with the following fields:
1609-
#' * `id`: The identifier for the tag.
1610-
#' * `name`: The name of the tag.
1611-
#' * `parent_id`: The identifier for the parent tag. Null if the tag is a
1612-
#' top-level tag.
1613-
#' * `created_time`: The timestamp (RFC3339) indicating when the tag was
1614-
#' created.
1615-
#' * `updated_time`: The timestamp (RFC3339) indicating when the tag was
1616-
#' last updated.
1617-
#' * `owner`: Basic details about the owner of this content item. Each entry
1618-
#' is a list with the following fields:
1619-
#' * `guid`: The user's GUID, or unique identifier, in UUID RFC4122 format.
1620-
#' * `username`: The user's username.
1621-
#' * `first_name`: The user's first name.
1622-
#' * `last_name`: The user's last name.
1507+
#' A list of [Content] objects.
16231508
#'
16241509
#' @details
16251510
#' Please see https://docs.posit.co/connect/api/#get-/v1/search/content for more
@@ -1630,7 +1515,13 @@ get_content_packages <- function(content) {
16301515
#' library(connectapi)
16311516
#' client <- connect()
16321517
#'
1633-
#' search_content(client, q = "")
1518+
#' my_content <- search_content(client, q = "owner:@me")
1519+
#'
1520+
#' shiny_content <- purrr::keep(my_content, function(x) {
1521+
#' x$content$app_mode == "rmd-shiny"
1522+
#' })
1523+
#'
1524+
#' purrr::map(shiny_content, lock_content)
16341525
#' }
16351526
#'
16361527
#' @family content functions
@@ -1645,7 +1536,7 @@ search_content <- function(
16451536
) {
16461537
error_if_less_than(client$version, "2024.04.0")
16471538

1648-
page_offset(
1539+
res <- page_offset(
16491540
client,
16501541
req = .search_content(
16511542
client,
@@ -1656,6 +1547,10 @@ search_content <- function(
16561547
),
16571548
limit = limit
16581549
)
1550+
1551+
purrr::map(res, function(x) {
1552+
Content$new(client, x)
1553+
})
16591554
}
16601555

16611556
.search_content <- function(

man/Content.Rd

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/search_content.Rd

Lines changed: 8 additions & 125 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-content.R

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,15 @@ with_mock_dir("2025.09.0", {
478478
test_that("content search returns the expected list of content", {
479479
res <- search_content(client, q = "sea bream")
480480
expect_equal(
481-
purrr::map_chr(res, "guid"),
481+
class(res[[1]]),
482+
c("Content", "R6")
483+
)
484+
expect_equal(
485+
purrr::map_chr(res, list("content", "guid")),
482486
c("c9f68287", "53032a0e")
483487
)
484488
expect_equal(
485-
purrr::map_chr(res, "title"),
489+
purrr::map_chr(res, list("content", "title")),
486490
c("sea bream report", "sea bream dashboard")
487491
)
488492
})
@@ -491,7 +495,7 @@ with_mock_dir("2025.09.0", {
491495
res <- search_content(client, q = "blobfish")
492496
expect_equal(length(res), 3)
493497
expect_equal(
494-
purrr::map_chr(res, "title"),
498+
purrr::map_chr(res, list("content", "title")),
495499
c("blobfish dashboard", "blobfish api", "blobfish report")
496500
)
497501
})

0 commit comments

Comments
 (0)