in src/recommendations/src/recommendations-service/app.py [0:0]
def get_products(feature, user_id, current_item_id, num_results, default_campaign_arn_param_name,
default_filter_arn_param_name, user_reqd_for_campaign=False, fully_qualify_image_urls=False,
):
""" Returns products given a UI feature, user, item/product.
If a feature name is provided and there is an active experiment for the
feature, the experiment will be used to retrieve products. Otherwise,
the default behavior will be used which will look to see if an Amazon Personalize
campaign is available. If not, the Product service will be called to get products
from the same category as the current product.
Args:
feature: Used to track different experiments - different experiments pertain to different features
user_id: If supplied we are looking at user personalization
current_item_id: Or maybe we are looking at related items
num_results: Num to return
default_campaign_arn_param_name: If no experiment active, use this SSM parameters to get recommender Arn
default_filter_arn_param_name: If no experiment active, use this SSM parameter to get filter Arn, if exists
user_reqd_for_campaign: Require a user ID to use Personalze - otherwise default
fully_qualify_image_urls: Fully qualify image URLs n here
Returns:
A prepared HTTP response object.
"""
# Check environment for host and port first in case we're running in a local Docker container (dev mode)
products_service_host = os.environ.get('PRODUCT_SERVICE_HOST')
products_service_port = os.environ.get('PRODUCT_SERVICE_PORT', 80)
if not products_service_host:
# Get product service instance. We'll need it rehydrate product info for recommendations.
response = servicediscovery.discover_instances(
NamespaceName='retaildemostore.local',
ServiceName='products',
MaxResults=1,
HealthStatus='HEALTHY'
)
products_service_host = response['Instances'][0]['Attributes']['AWS_INSTANCE_IPV4']
items = []
resp_headers = {}
experiment = None
exp_manager = None
# Get active experiment if one is setup for feature and we have a user.
if feature and user_id:
exp_manager = ExperimentManager()
experiment = exp_manager.get_active(feature)
if experiment:
# Get items from experiment.
tracker = exp_manager.default_tracker()
items = experiment.get_items(
user_id = user_id,
current_item_id = current_item_id,
num_results = num_results,
tracker = tracker
)
resp_headers['X-Experiment-Name'] = experiment.name
resp_headers['X-Experiment-Type'] = experiment.type
resp_headers['X-Experiment-Id'] = experiment.id
else:
# Fallback to default behavior of checking for campaign ARN parameter and
# then the default product resolver.
values = get_parameter_values([default_campaign_arn_param_name, default_filter_arn_param_name])
campaign_arn = values[0]
filter_arn = values[1]
if campaign_arn and (user_id or not user_reqd_for_campaign):
logger.info(f"get_products: Supplied campaign: {campaign_arn} (from {default_campaign_arn_param_name}) Supplied filter: {filter_arn} (from {default_filter_arn_param_name}) Supplied user: {user_id}")
resolver = PersonalizeRecommendationsResolver(campaign_arn = campaign_arn, filter_arn = filter_arn)
items = resolver.get_items(
user_id = user_id,
product_id = current_item_id,
num_results = num_results
)
resp_headers['X-Personalize-Recipe'] = get_recipe(campaign_arn)
else:
resolver = DefaultProductResolver(products_service_host = products_service_host, products_service_port = products_service_port)
items = resolver.get_items(product_id = current_item_id, num_results = num_results)
item_ids_csv = ','.join([item['itemId'] for item in items])
url = f'http://{products_service_host}:{products_service_port}/products/id/{item_ids_csv}?fullyQualifyImageUrls={fully_qualify_image_urls}'
app.logger.debug(f"Asking for product info from {url}")
response = requests.get(url)
if response.ok:
products = response.json()
for item in items:
item_id = item['itemId']
product = next((p for p in products if p['id'] == item_id), None)
if product is not None and 'experiment' in item and 'url' in product:
# Append the experiment correlation ID to the product URL so it gets tracked if used by client.
product_url = product.get('url')
if '?' in product_url:
product_url += '&'
else:
product_url += '?'
product_url += 'exp=' + item['experiment']['correlationId']
product['url'] = product_url
item.update({
'product': product
})
item.pop('itemId')
resp = Response(json.dumps(items, cls=CompatEncoder), content_type = 'application/json', headers = resp_headers)
return resp