Skip to main content

Copy Feature Flag Definitions Between Projects

Last updated on

Overview

You can use Python and the Admin API to copy feature flag definitions (including individual targeting, targeting rules, and treatments) from a source project or environment to a target project or environment. This works either across different Harness accounts or within the same Harness account.

Prerequisites

Configuration

Before running the script:

  1. Configure the source API key, projects, and environments.
  2. Configure the target API key and traffic type.

Run the script to copy feature flags and definitions. If your flags reference segments, you’ll need to create those segments in the target account before running the script.

from splitapiclient.main import get_client

#############################################
sourceAPIKey="<SOURCE_ADMIN_API_KEY>"
sourceProjectNames=["<PROJECT>"]
sourceEnvironmentNames=["<ENV_1>", "<ENV_2>"]
targetTrafficTypeName = "user"
targetAPIKey="<TARGET_ADMIN_API_KEY>"
#############################################

sourceClient = get_client({'apikey': sourceAPIKey})
targetClient = get_client({'apikey': targetAPIKey})

for sourceProjectName in sourceProjectNames:
for sourceEnvironmentName in sourceEnvironmentNames:
print("Copying flags from ", sourceProjectName, " ", sourceEnvironmentName)
sourceWs = sourceClient.workspaces.find(sourceProjectName)
sourceEnv = sourceClient.environments.find(sourceEnvironmentName, sourceWs.id)
splits = sourceClient.split_definitions.list(sourceEnv.id, sourceWs.id)
for split in splits:
print(split.name, " is being copied")
splitMeta = sourceClient.splits.find(split.name, sourceWs.id)

if (targetTrafficTypeName != splitMeta._trafficType._name):
continue
trs = []
for tr in split._treatments:
trs.append(tr.export_dict())
rls = []
for rl in split._rules:
rls.append(rl.export_dict())
drls = []
for drl in split._default_rule:
drls.append(drl.export_dict())
splitDefinition = {"treatments": trs, "defaultTreatment": split._default_treatment, "rules": rls, "defaultRule": drls}
targetWs = targetClient.workspaces.find(sourceProjectName)
targetEnv = targetClient.environments.find(sourceEnvironmentName, targetWs.id)
if(targetClient.splits.find(split._name, targetWs.id)):
print('Split Meta already exists for Project: ', sourceProjectName, ' Flag: ', split._name)
split=targetClient.splits.find(split._name, targetWs.id)
else:
print('Creating Split Meta for Project: ', sourceProjectName, ' Flag: ', split._name)
split = targetWs.add_split({'name': split._name, 'description': splitMeta._description}, targetTrafficTypeName)

if(targetClient.split_definitions.find(split._name, targetEnv.id, targetWs.id)):
print('Updating Split Definition for Project: ', sourceProjectName, ' Environment: ', sourceEnvironmentName, ' Flag: ', split._name)
splitDef = targetClient.split_definitions.find(split._name, targetEnv.id, targetWs.id)
splitDef = splitDef.update_definition(splitDefinition)
else:
print('Adding Split Definition for Project: ', sourceProjectName, ' Environment: ', sourceEnvironmentName, ' Flag: ', split._name)
splitDef = split.add_to_environment(targetEnv.id, splitDefinition)