Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amplitude recommend personalize workshop #395

Draft
wants to merge 45 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1865f5f
working Amplitude and Personalize file writers
manbearshark Sep 14, 2022
15768bb
cleaned up errors + data quality
manbearshark Sep 15, 2022
d526c19
fixed time compression issue in generator
manbearshark Sep 17, 2022
4f04072
removed comments
manbearshark Sep 17, 2022
919ec89
minutes back to seconds for gen time
manbearshark Sep 17, 2022
feb717a
added check to timestamp duration
manbearshark Sep 18, 2022
0006285
cleaned up amplitude api keys
manbearshark Sep 22, 2022
6a97bb7
removed amplitude api key
manbearshark Sep 22, 2022
1f67ad5
cast float time to int
manbearshark Sep 23, 2022
5cec7cb
testing amplitude user identify
manbearshark Sep 28, 2022
d5de489
log amp id
manbearshark Sep 28, 2022
97f2d3a
generate a correct amp user id to match gen data
manbearshark Sep 28, 2022
c20d47c
log amp string instead
manbearshark Sep 28, 2022
550bfbb
define ampID
manbearshark Sep 28, 2022
834c830
amplitude identify function
manbearshark Sep 28, 2022
75e6b89
add identify; add required env params
manbearshark Sep 28, 2022
57b164a
add webui app config spec
manbearshark Sep 28, 2022
ad2e9b2
added amplitude recs api requests
manbearshark Sep 28, 2022
99cbbab
added amplitude results to main.vue
manbearshark Sep 28, 2022
4bb7b3b
revert to older version
manbearshark Sep 28, 2022
bebfd4b
log responses to test amp API
manbearshark Sep 29, 2022
1c6baa6
added error checking for amp call
manbearshark Sep 29, 2022
5f1ec3f
fix compile errors
manbearshark Sep 29, 2022
855c10e
fixed function name error
manbearshark Sep 29, 2022
53d526a
added amplitude env vars
manbearshark Oct 1, 2022
af05f5a
added amp recs experiment
manbearshark Oct 2, 2022
77fe202
added logging to amp results
manbearshark Oct 2, 2022
771ac6e
removed import error
manbearshark Oct 2, 2022
e72190a
add env vars to docker.yml for recs svc
manbearshark Oct 2, 2022
0a33add
log when ampl activated
manbearshark Oct 2, 2022
7becc9e
logging for amp rec id
manbearshark Oct 2, 2022
62341f9
log in main app
manbearshark Oct 2, 2022
c138d92
logging try #4
manbearshark Oct 2, 2022
d8c46e0
logging with print
manbearshark Oct 2, 2022
e0b4396
remove request log spam
manbearshark Oct 2, 2022
aa0fd33
fixed container ssm param bug
manbearshark Oct 2, 2022
5ef5f68
saved correct settings string
manbearshark Oct 2, 2022
7314cc6
update logging
manbearshark Oct 2, 2022
bb2305e
check for feature type
manbearshark Oct 2, 2022
5120abd
set test data
manbearshark Oct 2, 2022
b80b6bb
added item / experiment to results
manbearshark Oct 3, 2022
d14ac54
logic for amp rec items
manbearshark Oct 3, 2022
b432386
fixed class error
manbearshark Oct 3, 2022
137a5d5
removed comments
manbearshark Oct 3, 2022
ad8c7fd
added event send option to send script
manbearshark Oct 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions aws/cloudformation-templates/base/_template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ Parameters:
Description: Amplitude API key for product analytics and A/B testing results (optional).
NoEcho: true

AmplitudeSecretApiKey:
Type: String
Description: Amplitude secret API key from you project - this is used for the Profile API
NoEcho: true

AmplitudeRecommendationID:
Type: String
Description: Amplitude Receommender ID from the Recommender Details page
NoEcho: false

ParentStackName:
Type: String
Description: Parent stack name
Expand Down Expand Up @@ -269,6 +279,8 @@ Resources:
StackBucketName: !GetAtt Buckets.Outputs.StackBucketName
ExperimentStrategyTableName: !GetAtt Tables.Outputs.ExperimentStrategyTable
AmplitudeApiKey: !Ref AmplitudeApiKey
AmplitudeSecretApiKey: !Ref AmplitudeSecretApiKey
AmplitudeRecommendationID: !Ref AmplitudeRecommendationID
OptimizelySdkKey: !Ref OptimizelySdkKey
SegmentWriteKey: !Ref SegmentWriteKey
mParticleOrgId: !Ref mParticleOrgId
Expand Down
32 changes: 31 additions & 1 deletion aws/cloudformation-templates/base/ssm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ Parameters:
Description: Amplitude API key for product analytics and A/B testing results (optional).
NoEcho: true

AmplitudeSecretApiKey:
Type: String
Description: Amplitude secret API key from you project - this is used for the Profile API
NoEcho: true

AmplitudeRecommendationID:
Type: String
Description: Amplitude Receommender ID from the Recommender Details page
NoEcho: false

OptimizelySdkKey:
Type: String
Description: Optimizely SDK key for experimentation (optional).
Expand Down Expand Up @@ -61,6 +71,10 @@ Parameters:
Conditions:
HasAmplitudeApiKey:
!Not [!Equals [!Ref AmplitudeApiKey, ""]]
HasAmplitudeSecretApiKey:
!Not [!Equals [!Ref AmplitudeSecretApiKey, ""]]
HasAmplitudeRecommendationID:
!Not [!Equals [!Ref AmplitudeRecommendationID, ""]]
HasOptimizelySdkKey:
!Not [!Equals [!Ref OptimizelySdkKey, ""]]
HasSegmentWriteKey:
Expand Down Expand Up @@ -180,11 +194,27 @@ Resources:
ParameterAmplitudeApiKey:
Type: "AWS::SSM::Parameter"
Properties:
Name: "retaildemostore-amplitude-api-key"
Name: "/retaildemostore/webui/amplitude_api_key"
Type: "String"
Value: !If [HasAmplitudeApiKey, !Ref AmplitudeApiKey, "NONE"]
Description: "Retail Demo Store Amplitude API key"

ParameterAmplitudeSecretApiKey:
Type: "AWS::SSM::Parameter"
Properties:
Name: "/retaildemostore/webui/amplitude_secret_api_key"
Type: "String"
Value: !If [HasAmplitudeSecretApiKey, !Ref AmplitudeSecretApiKey, "NONE"]
Description: "Retail Demo Store Amplitude secret API key"

ParameterAmplitudeRecommendationID:
Type: "AWS::SSM::Parameter"
Properties:
Name: "/retaildemostore/webui/amplitude_recommendation_id"
Type: "String"
Value: !If [HasAmplitudeRecommendationID, !Ref AmplitudeRecommendationID, "NONE"]
Description: "Retail Demo Store Amplitude Recommender ID (see Recommender Details page)"

ParameterOptimizelySdkKey:
Type: "AWS::SSM::Parameter"
Properties:
Expand Down
13 changes: 0 additions & 13 deletions aws/cloudformation-templates/services/_template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@ Parameters:
Type: String
Description: SSM parameter name for the Personalize event tracking ID

ParameterAmplitudeApiKey:
Type: String
Description: SSM parameter name for the Amplitude API key

ParameterOptimizelySdkKey:
Type: String
Description: SSM parameter name for the Optimizely SDK key
Expand Down Expand Up @@ -160,7 +156,6 @@ Resources:
CategoriesTable: !Ref CategoriesTable
ExperimentStrategyTable: !Ref ExperimentStrategyTable
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -193,7 +188,6 @@ Resources:
ClusterName: !Ref ClusterName
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
PinpointAppId: !Ref PinpointAppId
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
Expand Down Expand Up @@ -227,7 +221,6 @@ Resources:
ClusterName: !Ref ClusterName
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -260,7 +253,6 @@ Resources:
ClusterName: !Ref ClusterName
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -294,7 +286,6 @@ Resources:
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
EnvOpenSearchDomainEndpoint: !Ref EnvOpenSearchDomainEndpoint
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -328,7 +319,6 @@ Resources:
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
EnvOpenSearchDomainEndpoint: !Ref EnvOpenSearchDomainEndpoint
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -362,7 +352,6 @@ Resources:
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
EnvOpenSearchDomainEndpoint: !Ref EnvOpenSearchDomainEndpoint
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -398,7 +387,6 @@ Resources:
CategoriesTable: !Ref CategoriesTable
ExperimentStrategyTable: !Ref ExperimentStrategyTable
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !GetAtt DeleteRepositoryLambdaFunction.Arn
Expand Down Expand Up @@ -431,7 +419,6 @@ Resources:
ClusterName: !Ref ClusterName
ServiceDiscoveryNamespace: !Ref ServiceDiscoveryNamespace
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
ParameterIVSVideoChannelMap: !Ref ParameterIVSVideoChannelMap
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ Resources:
SearchServiceExternalUrl: !Ref SearchServiceExternalUrl
PinpointAppId: !Ref PinpointAppId
ParameterPersonalizeEventTrackerId: !Ref ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !Ref ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !Ref ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !Ref CleanupBucketLambdaArn
DeleteRepositoryLambdaArn: !Ref DeleteRepositoryLambdaArn
Expand Down
7 changes: 0 additions & 7 deletions aws/cloudformation-templates/services/service/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ Parameters:
ParameterPersonalizeEventTrackerId:
Type: String

ParameterAmplitudeApiKey:
Type: String
Description: SSM parameter name for the Amplitude API key

ParameterOptimizelySdkKey:
Type: String
Description: SSM parameter name for the Optimizely SDK key
Expand Down Expand Up @@ -320,9 +316,6 @@ Resources:
- Name: PERSONALIZE_TRACKING_ID
Type: PARAMETER_STORE
Value: !Ref ParameterPersonalizeEventTrackerId
- Name: AMPLITUDE_API_KEY
Type: PARAMETER_STORE
Value: !Ref ParameterAmplitudeApiKey
- Name: OPTIMIZELY_SDK_KEY
Type: PARAMETER_STORE
Value: !Ref ParameterOptimizelySdkKey
Expand Down
4 changes: 4 additions & 0 deletions aws/cloudformation-templates/services/service/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ Resources:
Secrets:
- Name: OPTIMIZELY_SDK_KEY
ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore-optimizely-sdk-key'
- Name: AMPLITUDE_SECRET_API_KEY
ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore/webui/amplitude_secret_api_key'
- Name: AMPLITUDE_RECOMMENDATION_ID
ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore/webui/amplitude_recommendation_id'
- Name: SEGMENT_WRITE_KEY
ValueFrom: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/retaildemostore-segment-write-key'
Environment:
Expand Down
20 changes: 18 additions & 2 deletions aws/cloudformation-templates/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Metadata:
default: "Optional Integrations"
Parameters:
- AmplitudeApiKey
- AmplitudeSecretApiKey
- AmplitudeRecommendationID
- OptimizelySdkKey
- IncludeSegmentDependencies
- SegmentWriteKey
Expand Down Expand Up @@ -117,6 +119,10 @@ Metadata:
default: "Deploy personalized offers and pickup notices using Location Services geofencing"
AmplitudeApiKey:
default: "Amplitude API Key"
AmplitudeSecretApiKey:
default: "Amplitude Project Secret API Key"
AmplitudeRecommendationID:
default: "Amplitude Recommender ID (from the Recommender Details page)"
OptimizelySdkKey:
default: "Optimizely SDK Key"
AmazonPayStoreId:
Expand Down Expand Up @@ -292,6 +298,16 @@ Parameters:
Description: Amplitude API key for integrated product analytics and A/B testing results (optional).
NoEcho: true

AmplitudeSecretApiKey:
Type: String
Description: Amplitude secret API key from you project - this is used for the Profile API
NoEcho: true

AmplitudeRecommendationID:
Type: String
Description: Amplitude Receommender ID from the Recommender Details page
NoEcho: false

OptimizelySdkKey:
Type: String
Description: Optimizely SDK key for experimentation (optional).
Expand Down Expand Up @@ -505,6 +521,8 @@ Resources:
CreateOpenSearchServiceLinkedRole: !Ref CreateOpenSearchServiceLinkedRole
CleanupBucketLambdaArn: !GetAtt CleanupBucket.Outputs.LambdaFunctionArn
AmplitudeApiKey: !Ref AmplitudeApiKey
AmplitudeSecretApiKey: !Ref AmplitudeSecretApiKey
AmplitudeRecommendationID: !Ref AmplitudeRecommendationID
ParentStackName: !Ref AWS::StackName
OptimizelySdkKey: !Ref OptimizelySdkKey
SegmentWriteKey: !Ref SegmentWriteKey
Expand Down Expand Up @@ -554,7 +572,6 @@ Resources:
CategoriesTable: !GetAtt Base.Outputs.CategoriesTable
ExperimentStrategyTable: !GetAtt Base.Outputs.ExperimentStrategyTable
ParameterPersonalizeEventTrackerId: !GetAtt Base.Outputs.ParameterPersonalizeEventTrackerId
ParameterAmplitudeApiKey: !GetAtt Base.Outputs.ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !GetAtt Base.Outputs.ParameterOptimizelySdkKey
CleanupBucketLambdaArn: !GetAtt CleanupBucket.Outputs.LambdaFunctionArn
ParameterIVSVideoChannelMap: !GetAtt Base.Outputs.ParameterIVSVideoChannelMap
Expand Down Expand Up @@ -618,7 +635,6 @@ Resources:
!GetAtt Location.Outputs.LocationNotificationEndpoint,
"NotDeployed",
]
ParameterAmplitudeApiKey: !GetAtt Base.Outputs.ParameterAmplitudeApiKey
ParameterOptimizelySdkKey: !GetAtt Base.Outputs.ParameterOptimizelySdkKey
ParameterSegmentWriteKey: !GetAtt Base.Outputs.ParameterSegmentWriteKey
ParameterGoogleAnalyticsMeasurementId: !GetAtt Base.Outputs.ParameterGoogleAnalyticsMeasurementId
Expand Down
7 changes: 0 additions & 7 deletions aws/cloudformation-templates/web-ui-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ Parameters:
ParameterPersonalizeEventTrackerId:
Type: String

ParameterAmplitudeApiKey:
Type: String
Description: SSM parameter name for the Amplitude API key parameter name

ParameterOptimizelySdkKey:
Type: String
Description: SSM Parameter name for the Optimizely SDK key parameter name
Expand Down Expand Up @@ -433,9 +429,6 @@ Resources:
- Name: PERSONALIZE_TRACKING_ID
Type: PARAMETER_STORE
Value: !Ref ParameterPersonalizeEventTrackerId
- Name: AMPLITUDE_API_KEY
Type: PARAMETER_STORE
Value: !Ref ParameterAmplitudeApiKey
- Name: OPTIMIZELY_SDK_KEY
Type: PARAMETER_STORE
Value: !Ref ParameterOptimizelySdkKey
Expand Down
3 changes: 0 additions & 3 deletions generators/datagenerator/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
from datagenerator.amplitude import AmplitudeIdentifyEvent, AmplitudeTrackEvent, AmplitudeSender
from datagenerator.file import FileEvent

# TODO: Add Personalize output file formatter
# TODO: Add Amplitude output formatter

class OutputFormatter:
def __init__(self, timestamp, user, platform, properties, name = None):
self.event = name
Expand Down
66 changes: 66 additions & 0 deletions generators/generate_amplitude_conversion_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import os
import requests
import uuid
import time
import json

amplitude_secret_key = '1795766d2d822cda9f4875654f9a6ee6'
amplitude_rec_id = 'xv8mseo'

conversion = .2

control_group = []
experiment_group = []

output_file_name = 'src/aws-lambda/personalize-pre-create-resources/data/amplitude/conversion_events.json'

conversion_event = 'Purchase'

timestamp_start = time.time() # Start of script timestamp
first_timestamp = timestamp_start - (60*60*24*2)

def write_events(user_group):
# Generate output file for experiment group
time_increment = (60*60*24*2) / len(experiment_group)

with open(output_file_name, 'w') as f:
timestamp = first_timestamp
for user in user_group:
amplitude_event = {
"event_type": conversion_event,
"time": int(timestamp * 1000), # Amplitude wants time in ms since the epoch, we have sec
"user_id": user['user_id'], # Amplitude wants a UID as a string with no less than 5 chars
"insert_id": str(uuid.uuid4()), # This is to prevent duplicates when re-running event gen scripts
"event_properties": {
"product_id": user['items'][1],
}
}

f.write(f'{json.dumps(amplitude_event)}\n')
timestamp += time_increment

for user_id in range(1000, 2500):
uid = f'{user_id:0>5}'
response = requests.get('https://profile-api.amplitude.com/v1/userprofile',
headers={'Authorization': f'Api-Key {amplitude_secret_key}'},
params={'user_id': uid, 'rec_id': amplitude_rec_id})
res = response.json()
items = []
is_user_in_control_group = True
if res:
for item in res['userData']['recommendations'][0]['items']:
items.append(item)

is_user_in_control_group = res['userData']['recommendations'][0]['is_control']

if is_user_in_control_group:
control_group.append({'user_id': uid, 'items': items})
else:
experiment_group.append({'user_id': uid, 'items': items})

#print(f'{uid} {is_user_in_control_group}')

write_events(experiment_group)
# split the control list by half
half_length = int(len(control_group) / 2)
write_events(control_group[half_length:])
Loading