Content Delivery - Posit Connect: Server API Cookbook (2023)

This section explains how to use the Connect Server APIs to create content in Posit Connect and implement the code associated with that content. These APIs can be used for all types of content powered by Posit Connect.

orstudio/connect-api-deploy-brilliantThe GitHub repository contains a brilliant sample application and uses the recipes in this section in deployment scripts that you can use as examples when creating your own workflows.

oConnect-Server-API-Referencescontains documentation for each of the endpoints used in these recipes.


Use these recipestriedcut and trustcurlingto execute HTTP requests. we use thatCONNECT_SERVERmiCONNECT_API_KEYEnvironment variables introduced infrompart of this cookbook.


Some examples below simplify processing JSON responses using a command line tool calledjq. details aboutjqand installation information can be found on yourproject website.


These recipes do not prescribe a single workflow. Some example workflows include:

  • Automate the creation of a new application with a unique name every quarter to analyze sales opportunities. The latest quarter includes new dashboard features, but you can't change previous quarters; These applications need to record this point in time.

  • An API that receives updates after your continuous integration environment has fully tested the supporting code for that API. These tests confirm that all updates remain backward compatible.

  • A team collaborates on an app during a two-week sprint cycle. Code is shared with Git and progress is tracked on GitHub issues. The team performs production updates at the end of each sprint using a Docker-based deployment environment.

  • Your organization doesn't allow data scientists to publish directly to the production server. Production updates are scheduled events triggered by successful user acceptance tests. A deployment engineer who is not an R user uses scripts to create and publish content to production by interacting with the Connect Server APIs.


The content delivery workflow consists of several steps:

  1. Create a new content item; Content can be provided multiple times.
  2. create a packageCapture your code and its dependencies.
  3. Upload the package filefor positive connection.
  4. optional,Set environment variableswhat the content needs at runtime.
  5. Deploy (activate) this package.and monitor your progress.
  6. Get updates for a task; Get the latest information on a dispatched operation.

You can create a new piece of content with each deployment or target the same piece of content repeatedly. It's a good idea to reuse existing content as you continue to develop this application or report. Create new content items for new artifacts.


You must create a new content element if you change the content type. For example, you can't wrap an R Markdown document into a content element that already has a Dash application running.

create content#

oPOST /v1/contentThe API is the endpoint used to create a new content item in Posit Connect. A JSON document is used as input. Connect Server APIReference describes the full set of fields that can be provided to this endpoint.

(Video) Shiny Usage Tracking in Posit Connect

Our example contains only two fields:Namemititle:

  • Name: This field is required and must be unique across all content in your account. It is a friendly URL-compatible identifier.

  • title: This field is optional and a user-friendly identifier is defined here. when set,titleis displayed in the Posit Connect panel insteadName.

Here's an example:

Export DATA='{"name": "shakespeare", "title": "Shakespeare-Wortwolken"}'curl --silent --show-error -L --max-redirs0--fail -X POST\-H"Permission: keypsCONNECT_API_KEY}" \--Data"psDATA}" \ "psCONNECT_SERVER}__api__/v1/content"# => {# => "guid": "ccbd1a41-90a0-4b7b-89c7-16dd9ad47eb5",# => "name": "shakespeare",# => "title": "Shakespeare-Wortwolken",# => ...# => "guid_propietario": "0b609163-aad5-4bfd-a723-444e446344e3",# => }

Additional content fields:

  • The JSON response is the complete set of content fields.
  • Fields that you did not specify when creating the content receive default values. EITHERConnect-Server-API-Referencesdescribes all the request and response fields for thePOST /v1/contentPoint.

Let's define aCONTENT_GUIDEnvironment variable that contains theGUIDof the content we just created. We use this variable in the remaining implementation examples:

Export CONTENT_GUID="ccbd1a41-90a0-4b7b-89c7-16dd9ad47eb5"

create a package#

The Posit Connect content pack is a point representation of your code. You can associate multiple packages with your content even if only one package is active. The active package is used to generate your report, run your application, and provide what you see when you visit this content in your browser.

Create packages that fit your workflow:

  • As you improve/improve your content
  • Equivalent to a Git commit or merge
  • After testing is complete, run in your continuous integration environment
  • After stakeholder review and approval

The package is uploaded to Posit Connect as.tar.gzArchive. you will use themTeerUtility to create this file. Before creating the file, let's think about what it should contain.

  • All source files used by your content. It is usually a collection of.R,.Rmd,.py, z.ipynbfiles Also add the necessary HTML, CSS and Javascript resources.

  • Data files, images, or other resources loaded when your content is run or viewed. Could be.png,.jpg,.gif,.csvfiles If your report uses an Excel spreadsheet as input, include it!

  • Amanifest.json. This JSON file describes your content requirements. For R content, this includes a complete snapshot of all your package requirements. EITHERmanifest.jsonis created withrsconnect::writeManifestFunction.

    • On the command line:

      # This directory should be your current working directory.Rscript -e'rsconnect::writeManifest()'
    • From an R console:

      # This directory should be your current working directory.rsconectar::write a manifesto()


      (Video) Kelly O'Briant | Build Your Ideal Showcase of Data Products | RStudio Connect 1.9.0

      please usersconectarVersion 0.8.15 or later when generating a manifest file.

    • For python-based content, you can use thersconnect-pythonPackage to createmanifest.json. Make sure the python environment you are using for your project is enabled, and create a manifest specific to your project type (diary,API,special feature,Bokeh, oilluminated):

      rsconnect write manifestpsTYPICAL}./

      Watch thersconnect-python-Documentationfor details.

    We recommend walking itmanifest.jsonin your source control system and regenerate it when you push new versions of your code, especially when you update packages or change their dependencies! Watch theUser's guidefor more information on how to create the manifest.


    omanifest.jsonLinked to an R Markdown site (eg.Book) must specify the content category "Website".

    # From an R console:rsconectar::write a manifesto(content category = "Property")


    If your Posit Connect installation uses off-host content execution with Kubernetes (a feature currently in beta), you can optionally specify which Image Connect to use when creating your content:

    # From an R console (this directory should be your current working directory):rsconectar::write a manifesto(image = "")
    # Using the `rsconnect-python` package:rsconnect write manifestpsTYPICAL}--Image""./

    You can only use an image configured by your administrator. You can view a list of available images by logging into Posit Connect and clickingdocumentationat the top of the page. Consult the user manual pages foreditor of the RmiPublish from the command linefor more details.

Create your package.tar.gzFile after collecting the set of files to include. Here's an example that archives a simple brilliant app; EITHERApplication.Rcontains the source R andDatais a directory with data files loaded by the application:

tar czf bundle.tar.gz manifest.json app.R datos

upload packages#

oCONTENT_GUIDThe environment variable is the content into which the package will be loaded. Packets are assigned to exactly one content.

we use thatPOST/v1/content/{guid}/packagesEndpoint for loading content packs using thepackage.tar.gzArchive as payload:

curl --silent --show-error -L --max-redirs0--fail -X POST\-H"Permission: keypsCONNECT_API_KEY}" \--binary-data @"package.tar.gz" \ "psCONNECT_SERVER}__api__/v1/content/psCONTENT_GUID}/Package"# => {"package_id":"485","package_size":162987}

The response from the upload end includes an identifier for the packet created and the number of bytes received.


OfHE MUSTbenutze o--binary-dataargument in favorcurling, which sends the data file without further processing. DoNObenutze o--DataArgument: Send data the same way a browser does when you "submit" a form, and it's not appropriate.

Extract the package ID from the upload response and assign it to aBUNDLE_IDEnvironmental variable:

Export BUNDLE_ID="485"

Set environment variables#

If your code depends on environment variables being set at runtime, for example to provide a token confidentially, you can use this recipe to set them:

# Create the JSON input to set the environment variables.SECRET_TOKEN=...DATA='[ {"name": "TAB", "wert": "'"psSECRET_TOKEN}"'"},{"name": "DATA_URL", "value": ""}]'# Set the environment variables.curl --silent --show-error -L --max-redirs0--make it -X PARCHE\-H"Permission: keypsCONNECT_API_KEY}" \--Data"psDATA}" \ "psCONNECT_SERVER}__api__/v1/content/psCONTENT_GUID}/Surroundings"# => ["DATA_URL","FICHA"]

deploy a package#

This recipe explains how to deploy or activate a loaded package. assume thatCONTENT_GUIDrefers to the target content element andBUNDLE_IDSpecifies the package to be deployed.

The package implementation triggers an asynchronous task that makes the loaded data available for viewing. The workflow applied to bundled files varies by content type.

This uses thePOST/v1/content/{guid}/implementarPoint:

Supervision:In this example, the cookie returned by the linked server is stored so that it can be passed to the task probe endpoint below. In a single node connection setup, the cookie can be omitted.

# Create the JSON entry that names the package to deploy.Export DATA='{"package_id":"'"psBUNDLE_ID}"'"}'# Activate an implementation.curl --silent --show-error -L --max-redirs0--fail -X POST\-H"Permission: keypsCONNECT_API_KEY}" \--Data"psDATA}" \-c Cookie.txt\ "psCONNECT_SERVER}__api__/v1/content/psCONTENT_GUID}/implant"# => {"id_tarea":"BkkakQAXicqIGxC1"}

The result of a deploy request includes a task ID that we use to query the progress of that deploy task:

Export TASK="BkkakQAXicqIGxC1"

homework survey#

The recipe explains how to check for updates for a task. It is assumed that the task ID exists in theTASKenvironmental variable.

oGET /v1/tasks/{id}endpoint retrieves the latest information about a distributed operation.

Supervision:In high availability deployments of clustered Connect, the task request must be fulfilled by the node running the task. It does this by ensuring that any cookies returned by the provisioning process are included in subsequent requests so that the load balancer can correctly route the request. In a single node setup, the cookie can be omitted.

There are two ways to search for task information:

  • You can request the output of the entire tasko
  • You can request an incremental task output

oFirstThe URL query argument controls the amount of data that is returned.

(Video) RStudio Team Demo | Build & Share Data Products Like The World’s Leading Companies

This is a typical initial request for the progress of a task. do not specifyFirstURL query argument, which means that all available results will be returned. YeahFirstvalue is not givenfirst = 0is assumed.

curl --silent --show-error -L --max-redirs0--fail\-H"Permission: keypsCONNECT_API_KEY}" \-b cookie.txt\ "psCONNECT_SERVER}__api__/v1/tasks/psTASK}?wait=1"# => {# => "id": "BkkakQAXicqIGxC1",# => "Salida": [# => "Create shiny app...",# => "Requested package R version 3.5.1; with...",# => ],# => "completed": false,# => "Code": 0,# => "Error": "",# => "last": 2# => }

owait = 1The argument tells the server to capture output for up to one second. This long query approach is an alternative to explicitly sleeping on your query cycle.

oequipmentfield in the response allows us to incrementally get the output of the task. Our original request returned two lines of output; We would like our next application to continue at this point.

Here's a task progress request that doesn't include the first two lines of output:

Export FIRST=2curl --silent --show-error -L --max-redirs0--fail\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONNECT_SERVER}__api__/v1/tasks/psTASK}?wait=1&first=psFIRST}"# => {# => "id": "BkkakQAXicqIGxC1",# => "Salida": [# => "Delete the old manifest.json file for the packrat transform.",# => "Create manifest.json for packrat transformation.",# => ],# => "completed": false,# => "Code": 0,# => "Error": "",# => "last": 4# => }

Get task progress step by step until the answer is marked complete. The last few lines of output are included in this response.

Export FIRST=86curl --silent --show-error -L --max-redirs0--fail\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONNECT_SERVER}__api__/v1/tasks/psTASK}?wait=1&first=psFIRST}"# => {# => "id": "BkkakQAXicqIGxC1",# => "Salida": [# => "Packrat build completed against R version: '3.4.4'",# => "Starting the Shiny application..."# => ],# => "done": true,# => "Code": 0,# => "Error": "",# => "last": 88# => }

Errors are indicated by a non-zero value in the response.CodeIt's aErrorNews. It is likely that thesalidastream also contains information to help you understand the cause of the error. For example, problems with installing Rpackages are shown in thesalida.

Access to content provided#

The provided content can be accessed from the Connect panel at the URL returned inpain_url:

# Get the dashboard URLDASHBOARD_URL=pscurl --silent --show-error -L --max-redirs0--fail\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONNECT_SERVER}__api__/v1/content/psCONTENT_GUID}" |jq -r .dashboard_url)

Content can also be accessed directly, without using the Connect dashboard frameworkcontent url:

# Get the URL of the contentCONTENT_URL=pscurl --silent --show-error -L --max-redirs0--fail\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONNECT_SERVER}__api__/v1/content/psCONTENT_GUID}" |jq -r .Inhalts-URL)

You can visit the CONTENT_URL in a browser or use it to access content like the Plumber or Flask APIs. For example, if you have implemented a plumber API that responds toCORREOorders in your/AssessPoint:

curl --silent --show-error -L --max-redirs0--fail -X POST\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONTENT_URL}Assess"

Deploy a new version#

You can deploy a new version of your content using the methods described above:

  • load a package
  • Deploy the package
  • Oversee the deployment task

If you run these tasks a second time, your API client must provide them.content_guidreturned when the content was first created.

Identify content by name#

Clients unable to save contentGUIDcan deliver a singleNameto identify the content item to update.

When creating your content, provide unique value in theNameCamping:

Export NAME="my-unique-application-name"Export DATA='{"Name":"'psNAME}'"}'curl --silent --show-error -L --max-redirs0--fail -X POST\-H"Permission: keypsCONNECT_API_KEY}" \--Data"psDATA}" \ "psCONNECT_SERVER}__api__/v1/content"
(Video) AZ-204 | Integrate caching and content delivery within solutions

By deploying an update, you can get the contentGUIDusing the name. Content names are guaranteed to be unique within an individual user's account, but it is possible for multiple users to create content with the same name. To ensure that only one piece of content is returned, specify theGUIDof the user account that created the content.

# Get the GUID of the content creator (owner of this API key)curl --silent --show-error -L --max-redirs0--fail -X GET\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONNECT_SERVER}__api__/v1/Benutzer"# => {# => "Email": "",# => "username": "username",# => ...# => "guid": "0b609163-aad5-4bfd-a723-444e446344e3",# => }OWNER_GUID=„0b609163-aad5-4bfd-a723-444e446344e3“# Search for the app by name and ownercurl --silent --show-error -L --max-redirs0--fail -X GET\-H"Permission: keypsCONNECT_API_KEY}" \ "psCONNECT_SERVER}__api__/v1/content?name=psNAME}&guid_owner=psOWNER_GUID}"# => [# => {# => "guid": "ccbd1a41-90a0-4b7b-89c7-16dd9ad47eb5",# => "name": "my-unique-application-name",# => ...# => "guid_propietario": "0b609163-aad5-4bfd-a723-444e446344e3",# => }# => ]CONTENT_GUID="ccbd1a41-90a0-4b7b-89c7-16dd9ad47eb5"

Then follow the usual upgrade steps and go through theCONTENT_GUIDwhen loading and deploying the package.


1. WISI x Verimatrix: Upgrade Hospitality Networks and Reclaim Bandwidth with the New ABR Receiver
2. Analysing Data with ChatGPT (Data Analysis and ML )
3. NEST Trading Terminal is my SUPERPOWER - Here's Why!
(P R Sundar)
4. Tech Weeklies - Content Delivery Networks: Under the hood - 06/20 - Jyrki Pulliainen
5. How To Create Google Maps API KEY For Free ( Easy Steps By Steps Instructions) 4K
6. The Future of Content: Decoupled CMSs, API-driven architectures, machine learning, augmented reality
(Four Kitchens)
Top Articles
Latest Posts
Article information

Author: Tyson Zemlak

Last Updated: 16/06/2023

Views: 6416

Rating: 4.2 / 5 (43 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Tyson Zemlak

Birthday: 1992-03-17

Address: Apt. 662 96191 Quigley Dam, Kubview, MA 42013

Phone: +441678032891

Job: Community-Services Orchestrator

Hobby: Coffee roasting, Calligraphy, Metalworking, Fashion, Vehicle restoration, Shopping, Photography

Introduction: My name is Tyson Zemlak, I am a excited, light, sparkling, super, open, fair, magnificent person who loves writing and wants to share my knowledge and understanding with you.