Promoting Content from Staging to Production
Problem
You’re using two Connect servers for staging and production, and want to promote deployed content from one to the other.
Solution
Unlike other examples, this recipe creates two client objects. One for the statging server and one for the production location. In this example, the source server is the staging server and target server is the production server. These concepts can be adjusted to fit your organizational needs.
Here we define the API keys and URL information inline. In your environment, please follow best practices to keep your credential information secure.
from posit import connect
= "0d23c00de05a787ec2079ef75a881cdb"
SOURCE_API_KEY = "https://staging.connect.example.com/"
SOURCE_URL = "f19eb24c1fde2370e621ccdaf347f15e"
TARGET_API_KEY = "https://connect.example.com/"
TARGET_URL
= connect.Client(api_key=SOURCE_API_KEY, url=SOURCE_URL)
source_client = connect.Client(api_key=TARGET_API_KEY, url=TARGET_URL) target_client
Next, obtain the content from the source server and the target server.
= "154bd2af-e8fa-4aa4-aab8-dcef701f4af9"
SOURCE_CONTENT_GUID = "2d178c46-4dca-40b0-bf22-a21e1cfb5b46"
TARGET_CONTENT_GUID
= source_client.content.get(SOURCE_CONTENT_GUID)
source_content = target_client.content.get(TARGET_CONTENT_GUID) target_content
Next, obtain the bundle you want to promote using a bundle identifier (id), then download the bundle archive.
= '1000'
BUNDLE_ID = 'bundle.tar.gz'
BUNDLE_FILE_NAME
= source_content.bundles.get(SOURCE_BUNDLE_ID)
source_bundle source_bundle.download(BUNDLE_FILE_NAME)
Next, create a new bundle on the target server by uploading the bundle archive.
= target_content.bundles.create(BUNDLE_FILE_NAME) target_bundle
Next, deploy the bundle on the target server. This starts a new deployment task on the target server to render the bundle.
= target_bundle.deploy() deployment_task
Finally, call the wait_for
method on the deployment task. The wait_for
method watches the deployment process and returns once it completes. Once the task is complete, check the exit_code
to see if it fails. A non-zero exit signifies that the task failed to complete successfully.
deployment_task.wait_for()assert deployment_task.exit_code == 0
Full example
from posit import connect
= 'bundle.tar.gz'
BUNDLE_FILE_NAME = '1000'
BUNDLE_ID = "0d23c00de05a787ec2079ef75a881cdb"
SOURCE_API_KEY = "154bd2af-e8fa-4aa4-aab8-dcef701f4af9"
SOURCE_CONTENT_GUID = "https://staging.connect.example.com/"
SOURCE_URL = "f19eb24c1fde2370e621ccdaf347f15e"
TARGET_API_KEY = "2d178c46-4dca-40b0-bf22-a21e1cfb5b46"
TARGET_CONTENT_GUID = "https://connect.example.com/"
TARGET_URL
= connect.Client(api_key=SOURCE_API_KEY, url=SOURCE_URL)
source_client = connect.Client(api_key=TARGET_API_KEY, url=TARGET_URL)
target_client
= source_client.content.get(SOURCE_CONTENT_GUID)
source_content = target_client.content.get(TARGET_CONTENT_GUID)
target_content
= source_content.bundles.get(SOURCE_BUNDLE_ID)
source_bundle
source_bundle.download(BUNDLE_FILE_NAME)
= target_content.bundles.create(BUNDLE_FILE_NAME)
target_bundle
= target_bundle.deploy()
deployment_task
deployment_task.wait_for()assert deployment_task.exit_code == 0
Unlike other examples, this recipe creates two client objects. One for the statging server and one for the production location. In this example, the source server is the staging server and target server is the production server. These concepts can be adjusted to fit your organizational needs.
Here we define the API keys and URL information inline. In your environment, please follow best practices to keep your credential information secure.
library(connectapi)
<- "0d23c00de05a787ec2079ef75a881cdb"
SOURCE_API_KEY <- "https://staging.connect.example.com/"
SOURCE_URL <- "f19eb24c1fde2370e621ccdaf347f15e"
TARGET_API_KEY <- "https://connect.example.com/"
TARGET_URL
<- connect(
source_client server = SOURCE_URL,
api_key = SOURCE_API_KEY
)<- connect(
target_client server = TARGET_URL,
api_key = TARGET_API_KEY
)
Next, using the content GUID, create a content object for the source content.
<- "154bd2af-e8fa-4aa4-aab8-dcef701f4af9"
SOURCE_CONTENT_GUID <- content_item(source_client, SOURCE_CONTENT_GUID) source_content
Next, download the most recent bundle for the content you wish to promote. Alternatively, you can download a specific bundle by passing its bundle ID to the bundle_id
argument of download_bundle()
.
<- 'bundle.tar.gz'
BUNDLE_FILE_NAME <- download_bundle(source_content, filename = BUNDLE_FILE_NAME) source_bundle
Next, deploy the bundle on the target server. This starts a new deployment task on the target server to render the bundle.
<- deploy(target_client, source_bundle, guid = TARGET_CONTENT_GUID) deployment_task
Finally, poll the returned task object to view the output from the server as it runs the deployment process.
poll_task(deployment_task)
Full example
library(connectapi)
<- "0d23c00de05a787ec2079ef75a881cdb"
SOURCE_API_KEY <- "https://staging.connect.example.com/"
SOURCE_URL <- "f19eb24c1fde2370e621ccdaf347f15e"
TARGET_API_KEY <- "https://connect.example.com/"
TARGET_URL
<- connect(
source_client server = SOURCE_URL,
api_key = SOURCE_API_KEY
)<- connect(
target_client server = TARGET_URL,
api_key = TARGET_API_KEY
)
<- "154bd2af-e8fa-4aa4-aab8-dcef701f4af9"
SOURCE_CONTENT_GUID <- content_item(source_client, SOURCE_CONTENT_GUID)
source_content
<- 'bundle.tar.gz'
BUNDLE_FILE_NAME <- download_bundle(source_content, filename = BUNDLE_FILE_NAME)
source_bundle
<- deploy(target_client, source_bundle, guid = TARGET_CONTENT_GUID)
deployment_task poll_task(deployment_task)
Discussion
Your organization may have multiple Connect servers where permissions and environments are segregated into a staging and production system.
Data scientists within your organization are responsible for creating applications and reports. They frequently iterate, experiment, and share updates. Content updates are continuously published to the staging server, which enables them to share work without affecting your business’s critical production content.
Once an application or report is ready for general use, the team undergoes peer review, testing, and final approval for production use. The data science team does not have user permissions to publish content to the production environment. Instead, the deployment team is responsible for this process to ensure a secure and predictable deployment. They have secure user accounts with access to the statging and production servers. An engineering on the deployment engineering team downloads the bundle archive from the staging environment and deploys it into production.