Finding Public Content
Problem
You need to identify all content on your Connect server with access permissions set to Anyone - no login required. For each piece of public access content, you need to know the URL, content owner, and when it was last updated.
Solution
Use the Posit SDK to get all content from the server, keeping only content with the all access type. Next, prepare the data. The owner column contains a JSON object with multiple fields, and we are only interested in the username. We also need to convert the last_deployed_time field to the correct data type.
from posit import connect
import pandas as pd
# Initialize a Connect client
client = connect.Client()
# Find all content with owner information included
content = client.content.find(include="owner")
# Convert to DataFrame and filter for public access content
content_df = pd.DataFrame(content)
public_content = content_df[content_df['access_type'] == 'all'].copy()
# Extract owner username and format date
public_content['Owner'] = public_content['owner'].apply(lambda x: x.get('username', 'Unknown'))
public_content['Updated'] = pd.to_datetime(public_content['last_deployed_time']).dt.date
# Select and rename columns for final output
content = public_content[['title', 'Owner', 'content_url', 'Updated']].rename(columns={
'title': 'Title',
'content_url': 'URL'
})The recipe produces a DataFrame with the required data.
>>> print(content)
Title Owner URL Updated
5 Cool Slideshow john_admin https://connect.example.org/content/bcb281fc-a... 2024-06-28
6 Sales Dashboard john_admin https://connect.example.org/content/83c54639-6... 2024-06-28
7 Manuscript john_admin https://connect.example.org/content/de5bd4e2-6... 2024-06-28Use connectapi to get all content from the server, keeping only content with the all access type. Next, prepare the data. The owner column contains a JSON object with multiple fields, and we are only interested in the username. We also need to convert the last_deployed_time field to the correct data type.
library(connectapi)
library(dplyr)
library(tidyr)
client <- connect()
# Get public access content
content <- get_content(client) |>
filter(access_type == "all")
# Process the data
content <- content |>
unnest_wider(col = c("owner"), names_sep = ".") |>
mutate(last_deployed_time = as.Date(last_deployed_time)) |>
select(c("Title" = title, "Owner" = owner.username, "URL" = content_url, "Updated" = last_deployed_time))The recipe produces a data frame with the required data.
> content
# A tibble: 768 × 4
Title Owner URL Updated
<chr> <chr> <chr> <date>
1 Cool Slideshow john_admin https://connect.example.org/content/bcb281fc-aa3b-4341-93eb-081814608c94/ 2024-06-28
2 Sales Dashboard john_admin https://connect.example.org/content/83c54639-6030-4054-8066-5011b9fb796d/ 2024-06-28
3 Manuscript john_admin https://connect.example.org/content/de5bd4e2-6ed5-49cb-99fa-8c6736cbcbaa/ 2024-06-28Creating an HTML table
Transform the URL into an HTML link, and use itable to display an HTML table.
import itables
def make_clickable(val):
return f'<a target="_blank" href="{val}">{val}</a>'
content = content.style.format({'URL': make_clickable})
itables.show(content)Discussion
The URLs in the list can be used to audit the access within networks, i.e., you can check to see whether content marked as public access is reachable outside your organization’s network or not.
You can use the Content usage recipe to check the usage of each content item.
The list above also identifies the content publisher, who can be reached out to if there is a need to modify the access.

