Skip to content

Commit dc55d83

Browse files
toph-allenjonkeane
andauthored
feat: add pagination to search_content() (#449)
Co-authored-by: Jonathan Keane <[email protected]>
1 parent 8e8f85d commit dc55d83

File tree

7 files changed

+95
-136
lines changed

7 files changed

+95
-136
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
server: `create_integration()`, `update_integration()` and
1111
`delete_integration()`. (#434)
1212
- Support content search API with the `search_content()` function. (#272)
13+
- New `search_content()` function which lets you search and filter content items
14+
on the Connect server. (#272, #447)
1315

1416
# connectapi 0.8.0
1517

R/content.R

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,16 +1441,13 @@ get_content_packages <- function(content) {
14411441
#' @param q The search query, using the syntax described in the Connect
14421442
#' documentation on [content search
14431443
#' terms](https://docs.posit.co/connect/user/viewing-content/#searching-content)
1444-
#' @param page_number Integer. The page to return relative to the given `page_size`.
1445-
#' Must be greater than 0.
1446-
#' @param page_size Integer. The number of items to include in each page. This
1447-
#' parameter is "best effort" since there may not be enough results to honor the
1448-
#' request. If `page_size` is less than 1 or greater than 500, an error will be
1449-
#' returned.
14501444
#' @param include Comma-separated character string of values indicating additional
14511445
#' details to include in the response. Values can be `owner` and `vanity_url`;
14521446
#' both are included by default.
1453-
#' @param ... Extra arguments. Currently not used.
1447+
#' @param ... Extra arguments. Passing in `page_number` and `page_size` will
1448+
#' affect the internal pagination for Connect's content search API. Setting
1449+
#' `page_number` will change the page at which pagination *starts*, and
1450+
#' `page_size` will control the size of pages (max 500).
14541451
#'
14551452
#' @return
14561453
#' A list containing sub-fields:
@@ -1587,13 +1584,32 @@ get_content_packages <- function(content) {
15871584
search_content <- function(
15881585
client,
15891586
q = NULL,
1590-
page_number = 1,
1591-
page_size = 500,
15921587
include = "owner,vanity_url",
15931588
...
15941589
) {
15951590
error_if_less_than(client$version, "2024.04.0")
15961591

1592+
page_offset(
1593+
client,
1594+
req = .search_content(
1595+
client,
1596+
q = q,
1597+
include = include,
1598+
# page_size and page_number can be passed in via `...`. Since this call is
1599+
# still passed to page_offset, page_number affects the *starting* page,
1600+
# but pagination still continues.
1601+
...
1602+
)
1603+
)
1604+
}
1605+
1606+
.search_content <- function(
1607+
client,
1608+
q,
1609+
page_number = 1,
1610+
page_size = 500,
1611+
include
1612+
) {
15971613
path <- v1_url("search", "content")
15981614

15991615
query <- list(

man/search_content.Rd

Lines changed: 5 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,17 @@
1+
// Used in test-content.R
12
{
23
"total": 2,
4+
"current_page": 1,
35
"results": [
46
{
57
"guid": "c9f68287",
68
"name": "sea-bream-report",
7-
"title": "sea bream report",
8-
"description": "",
9-
"access_type": "all",
10-
"locked": false,
11-
"locked_message": "",
12-
"connection_timeout": null,
13-
"read_timeout": null,
14-
"init_timeout": null,
15-
"idle_timeout": null,
16-
"max_processes": null,
17-
"min_processes": null,
18-
"max_conns_per_process": null,
19-
"load_factor": null,
20-
"memory_request": null,
21-
"memory_limit": null,
22-
"cpu_request": null,
23-
"cpu_limit": null,
24-
"amd_gpu_limit": null,
25-
"nvidia_gpu_limit": null,
26-
"service_account_name": null,
27-
"default_image_name": null,
28-
"default_environment_guid": null,
29-
"created_time": "2024-08-29T17:52:30Z",
30-
"last_deployed_time": "2025-09-25T17:26:05Z",
31-
"bundle_id": "306864",
32-
"app_mode": "python-shiny",
33-
"content_category": "",
34-
"parameterized": false,
35-
"environment_guid": null,
36-
"cluster_name": "Local",
37-
"image_name": null,
38-
"r_version": null,
39-
"py_version": "3.10.17",
40-
"quarto_version": null,
41-
"r_environment_management": null,
42-
"default_r_environment_management": null,
43-
"py_environment_management": true,
44-
"default_py_environment_management": null,
45-
"run_as": null,
46-
"run_as_current_user": false,
47-
"owner_guid": "c2250bb4",
48-
"content_url": "https://connect.example/content/c9f68287/",
49-
"dashboard_url": "https://connect.example/connect/#/apps/c9f68287",
50-
"app_role": "none",
51-
"id": "57138",
52-
"owner": {
53-
"guid": "c2250bb4",
54-
"username": "toph_allen",
55-
"first_name": "Toph",
56-
"last_name": "Allen"
57-
},
58-
"public_content_status": null
9+
"title": "sea bream report"
5910
},
6011
{
6112
"guid": "53032a0e",
6213
"name": "sea-bream-dashboard",
63-
"title": "sea bream dashboard",
64-
"description": "",
65-
"access_type": "all",
66-
"locked": false,
67-
"locked_message": "",
68-
"connection_timeout": null,
69-
"read_timeout": null,
70-
"init_timeout": null,
71-
"idle_timeout": null,
72-
"max_processes": null,
73-
"min_processes": null,
74-
"max_conns_per_process": null,
75-
"load_factor": null,
76-
"memory_request": null,
77-
"memory_limit": null,
78-
"cpu_request": null,
79-
"cpu_limit": null,
80-
"amd_gpu_limit": null,
81-
"nvidia_gpu_limit": null,
82-
"service_account_name": null,
83-
"default_image_name": null,
84-
"default_environment_guid": null,
85-
"created_time": "2024-08-29T17:49:34Z",
86-
"last_deployed_time": "2025-09-25T17:23:21Z",
87-
"bundle_id": "306844",
88-
"app_mode": "python-shiny",
89-
"content_category": "",
90-
"parameterized": false,
91-
"environment_guid": null,
92-
"cluster_name": "Local",
93-
"image_name": null,
94-
"r_version": null,
95-
"py_version": "3.10.17",
96-
"quarto_version": null,
97-
"r_environment_management": null,
98-
"default_r_environment_management": null,
99-
"py_environment_management": true,
100-
"default_py_environment_management": null,
101-
"run_as": null,
102-
"run_as_current_user": false,
103-
"owner_guid": "c2250bb4",
104-
"content_url": "https://connect.example/content/53032a0e/",
105-
"dashboard_url": "https://connect.example/connect/#/apps/53032a0e",
106-
"app_role": "none",
107-
"id": "57137",
108-
"owner": {
109-
"guid": "c2250bb4",
110-
"username": "toph_allen",
111-
"first_name": "Toph",
112-
"last_name": "Allen"
113-
},
114-
"public_content_status": null
14+
"title": "sea bream dashboard"
11515
}
11616
]
11717
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Used in test-content.R
2+
{
3+
"total": 3,
4+
"current_page": 1,
5+
"results": [
6+
{
7+
"guid": "c9f68287",
8+
"name": "blobfish-dashboard",
9+
"title": "blobfish dashboard"
10+
},
11+
{
12+
"guid": "53032a0e",
13+
"name": "blobfish-api",
14+
"title": "blobfish api"
15+
}
16+
]
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Used in test-content.R
2+
{
3+
"total": 3,
4+
"current_page": 2,
5+
"results": [
6+
{
7+
"guid": "abc12345",
8+
"name": "blobfish-report",
9+
"title": "blobfish report"
10+
}
11+
]
12+
}

tests/testthat/test-content.R

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -478,26 +478,50 @@ 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$results, "owner_guid"),
482-
c("c2250bb4", "c2250bb4")
481+
purrr::map_chr(res, "guid"),
482+
c("c9f68287", "53032a0e")
483483
)
484484
expect_equal(
485-
purrr::map_chr(res$results, "title"),
485+
purrr::map_chr(res, "title"),
486486
c("sea bream report", "sea bream dashboard")
487487
)
488488
})
489489

490+
test_that("content search fetches multiple pages correctly", {
491+
res <- search_content(client, q = "blobfish")
492+
expect_equal(length(res), 3)
493+
expect_equal(
494+
purrr::map_chr(res, "title"),
495+
c("blobfish dashboard", "blobfish api", "blobfish report")
496+
)
497+
})
498+
490499
test_that("content search passes all parameters through correctly", {
491500
without_internet(
492501
expect_GET(
493502
search_content(
494503
client,
495504
q = "bream",
496-
include = "owner",
497505
page_number = 2,
498-
page_size = 5
506+
page_size = 20,
507+
include = "owner"
508+
),
509+
"https://connect.example/__api__/v1/search/content?q=bream&page_number=2&page_size=20&include=owner"
510+
)
511+
)
512+
})
513+
514+
test_that("the inner .search_content() func calls the endpoint correctly", {
515+
without_internet(
516+
expect_GET(
517+
.search_content(
518+
client,
519+
q = "bream",
520+
page_number = 2,
521+
page_size = 20,
522+
include = "owner"
499523
),
500-
"https://connect.example/__api__/v1/search/content?q=bream&page_number=2&page_size=5&include=owner"
524+
"https://connect.example/__api__/v1/search/content?q=bream&page_number=2&page_size=20&include=owner"
501525
)
502526
)
503527
})

0 commit comments

Comments
 (0)