Giter Site home page Giter Site logo

aws-samples / retail-demo-store Goto Github PK

View Code? Open in Web Editor NEW
687.0 29.0 438.0 101.64 MB

AWS Retail Demo Store is a sample retail web application and workshop platform demonstrating how AWS infrastructure and services can be used to build compelling customer experiences for eCommerce, retail, and digital marketing use-cases

License: MIT No Attribution

Python 28.11% Shell 2.03% Go 1.57% Dockerfile 0.21% JavaScript 5.79% HTML 2.50% Vue 18.59% Jupyter Notebook 41.16% CSS 0.02% Makefile 0.01%
aws personalize pinpoint cognito ecs fargate amplify vuejs cloudfront codepipeline workshops ecommerce opensearch

retail-demo-store's Introduction

Retail Demo Store

A sample retail web application and workshop platform intended as an educational tool for demonstrating how AWS infrastructure and services can be used to build compelling customer experiences for eCommerce, retail, and digital marketing use-cases.

Build Status

Ruff UI Build

This project is intended for educational purposes only and not for production use.

Retail Demo Store Home Page

The Retail Demo Store is an eCommerce reference implementation designed to showcase how AWS services can be used to build compelling shopping experiences using modern architecture and design patterns.

At the heart of the Retail Demo Store is a collection of polyglot microservices hosted in Amazon Elastic Container Service (AWS Fargate) that represent domain constructs such as products, carts, orders, and users as well as services for search and recommendations. While the web user interface is served by Amazon CloudFront and Amazon S3.

The architecture is supported by several managed services including Amazon Cognito, Amazon Pinpoint, Amazon Personalize, and Amazon OpenSearch Service (successor to Amazon Elasticsearch Service). The web user interface is built using the Vue.js framework with AWS Amplify to provide integrations with Cognito for registration/authentication and event streaming to Pinpoint and Personalize (Event Tracker). Finally, AWS CodePipeline is leveraged to demonstrate how AWS development services can be used to orchestrate the build and deployment process with the Retail Demo Store.

Retail Demo Store Architecture

Deployment

Note

To deploy to your own AWS account please follow the Deployment Instructions that will explain how to easily get started by staging the retail demo store to your own AWS account.

Warning

Deploying this demo application in your AWS account will create and consume AWS resources, which will cost money. In addition, some features such as account registration via Amazon Cognito and the messaging workshop for Amazon Pinpoint require users to provide a valid email address and optionally a phone number to demonstrate completely. Therefore, to avoid ongoing charges and to clean up all data, be sure to follow all workshop clean up instructions and shutdown/remove all resources by deleting the CloudFormation stack once you are finished.

Important

The Retail Demo Store experience is for demonstration purposes only. You must comply with all applicable laws and regulations, including any laws and regulations related to email or text marketing, in any applicable country or region.

Supported Regions

The Retail Demo Store has been tested in the AWS regions indicated in the deployment instructions below.

Region Name Region Supported
US East (N. Virginia) us-east-1 Fully supported
US West (Oregon) us-west-2 Fully supported
Europe (Ireland) eu-west-1 Partial support (personalized product descriptions and thematic similar product descriptions not supported)
Europe (Frankfurt) eu-central-1 Partial support (thematic similar product descriptions not supported)
Asia Pacific (Tokyo) ap-northeast-1 Partial support (personalized product descriptions not supported)
Asia Pacific (Sydney) ap-southeast-2 Partial support (personalized product descriptions and thematic similar product descriptions not supported)

[Note] Additional regions may be supported depending on service availability and having the Retail Demo Store's deployment resources staged to an S3 bucket in the targeted region.

Hands-On Workshops

This project is designed to provide you with an environment in which you can learn to use AWS services to modify the behavior of an ecommerce application, based on business requirements. This can be done in a group setting or as an individual using self-paced workbooks. Currently there are workshops for adding search, personalization, experimentation frameworks, a/b testing, analytics, customer data platforms (CDPs), messaging, and more.

In order to use the workshops, you will need to deploy the Retail Demo Store into an AWS account, using one of the methods described in the Getting Started or Developers sections below. This is necessary because the workshops run in SageMaker Jupyter notebooks, which provide an interactive Python environment where you can execute code in the Retail Demo Store environment.

AWS Service Workshops Overview Workshop Links Level Duration
Amazon Personalize Amazon Personalize The Retail Demo Store uses Amazon Personalize to provide similar item recommendations, search re-ranking based on user preferences, and product recommendations based on user item interactions. The attached workshop is a throrough walk through of the major features of Amazon Personalize, and how it can be deployed in an ecommerce application like the Retail Demo Store. Personalize Setup 300 2-2.5 hours
Amazon Pinpoint Amazon Pinpoint In this workshop we will use Amazon Pinpoint to add the ability to dynamically send welcome messages, abandoned cart messages, and messages with personalized product recommendations to the customers of the Retail Demo Store. Email Campaigns 200 1 hour
Amazon Lex Amazon Lex In this module we're going to implement a conversational chatbot using Amazon Lex and integrate it into the Retail Demo Store's web UI. We'll provide some basic functionality to our chatbot such as being able to provide a return policy to users as well as wiring up the chatbot to the Amazon Personalize ML models we created in the Personalization workshop to provide personalized product recommendations to our users. Lex Chatbot 200 30 minutes
Amazon OpenSearch Amazon OpenSearch In this workshop, you will create a new index using Amazon OpenSearch Service and then index the Retail Demo Store product data so that users can search for products. Product Search 200 20 minutes
Amazon Location Services Amazon Location Services Create a geofence for customers approaching your physical store and send them timely pickup notifications and offers. Geofencing 300 2 hours
Amazon Alexa Amazon Alexa Incorporating Location Service, Personalize and Retail Demo Store into a hands-free ordering experience. Alexa skill deployment 300 60 minutes
Experimentation In this module we are going to add experimentation to the Retail Demo Store. This will allow us to experiment with different personalization approaches in the user interface. Through notebooks in this module we will demonstrate how to implement three experimentation techniques as well as how to use Amazon CloudWatch Evidently for A/B tests. Overview

A/B (400)

Interleaving (400)

Multi-Armed Bandit (400)

CloudWatch Evidently (200)
200/400 1.5 hours

Partner Integrations

Additionally, AWS partners have developed workshop content that enable you to learn how to integrate their solutions with the Retail Demo Store and the AWS services that it relies on, such as Amazon Personalize.

AWS Partner Workshops Overview Workshop Links Level Duration
In this workshop, you will set up tracking for Amplitude events, analyze user behavior prior to peronalization being deployed, and then measure the effects of personalization on user behavior after Personalize is deployed in the Retail Demo Store. Evaluating Personalization Performance 200 30 minutes
In this workshop we will use Braze to add the ability to personalize marketing messages to customers of the Retail Demo Store using customer behavioral data and the Personalize models you trained when setting up Amazon Personalize. Personalized Email Campaigns 200 1 hour
mParticle is a Customer Data Platform that allows any brand to ingest data from multiple sources in real-time, apply data quality and governance over the ingested data and orchestrate the data to any marketing and technology stack your organization is using. In this workshop, you will configure real-time event flows to Amazon Personalize using the mParticle SDKs and then use that data to create customer profiles that can be used in marketing campaigns to customers via Braze. Real Time Personalization Events

Personalized Customer Profiles and Messaging with any marketing tool (Braze) and mParticle
300 1-1.5 hours
In this exercise we will define, launch, and evaluate the results of an A/B experiment of a personalized user experience using Optimizely. AB Experiments for Personalization 200 30 minutes
Segment is a real-time events pipeline for customer data, as well as a customer data platform. In the Retail Demo Store, Segment is used to deliver real-time events from the web user interface to Amazon Personalize. These real-time events are also used to create customer profile with Amazon Personalize recommendations appended, which can then be used via the CDP to push data to marketing tools. Real Time Personalization Events

Customer Data Platforms and Personalize
300 1-1.5 hours
Layer0 extends the capabilities of a traditional CDN by not only hosting your static content, but also providing server-side rendering for progressive web applications. Layer0 allows caching both your APIs and HTML at the network edge to provide your users with the fastest browsing experience. Teams can ship faster leveraging an enhanced developer experience to deploy code faster and with more frequency, view their code quickly in atomically deployed environments, and integrating their CDN configuration to the overall build process. Layer0 provides the tools needed to build the modern apps capable of providing the performance expected by modern consumers. Edge Optimization 200 1 hour

Notes:

Amazon Personalize Campaigns

If you chose to have the Amazon Personalize campaigns automatically built post-deployment, this process will take an additional 2-2.5 hours. This process happens in the background so you don't have to wait for it to complete before exploring the Retail Demo Store application and architecture. Once the Personalize campaigns are created, they will be automatically activated in the Web UI and Recommendations service. You can monitor the progress in CloudWatch under the /aws/lambda/RetailDemoStorePersonalizePreCreateCampaigns log group.

Amazon Pinpoint Campaigns

If you chose to have the Amazon Pinpoint campaigns automatically built (‘Auto-Configure Pinpoint’ is set to ‘Yes’ in the CloudFormation template), this process will take an additional 20-30 minutes. Once the Pinpoint campaigns are created, they will be automatically visbile in the Web UI. However, there are some manual steps described below that are required for enabling the Pinpoint channels.

Pinpoint Emails:

PinpointEmailFromAddress: By Default, AWS Accounts have emails set up in a sandbox environement. To enable the functionality, you need to complete either of the following manual steps.

  • Verifying the email addresses you want to send and receive emails from. More info here. This is the easiest and recommended approach for demos and workshops.
  • Request to be removed from the sandbox environment. More info here. This is recommended only for production workloads and the Retail Demo Store is intended to be used for demonstration purposes only.

Pinpoint SMS

PinpointSMSLongCode: A dedicated long code (i.e. a phone number) obtained for Amazon Pinpoint to send and receive messages at. You also need to enable two way SMS for this long code using Pinpoint. Follow steps 2 and 3 in the Enable Pinpoint SMS Channel & Obtain Dedicated Long Code section of the Pinpoint workshop to get a long code and enable two way SMS for it. When deploying Retail Demo Store, enter the number as a parameter. The number should be formatted along with the country code and without any spaces or brackets. For Example: enter “+1XXXXXXXXXX” for a long code based in the United States.

Amazon Bedrock Demos

Amazon Bedrock users need to request access to models before they are available for use. To demo Personalised Product Descriptions make sure to enable access to Anthropic's Claude v2 via the Amazon Bedrock Management Console. Instructions on enabling model access can be found here. Amazon Bedrock is currently available in 5 regions globally, US East (N. Virginia), US West (Oregon), Asia Pacific (Tokyo), Europe (Frankfurt) and Asia Pacific (Singapore).

Using the Retail Demo Store Web Application

Once you launch the CloudFormation stack, all of the services will go through a build and deployment cycle and deploy the Retail Demo Store.

Compiling and deploying the web UI application and the services it uses can take some time. You can monitor progress in CodePipeline. Until this completes, you may see a Sample Application when accessing the public WebUI URL.

You can find the URL for the Retail Demo Store Web UI in the Outputs of your main CloudFormation stack (called retaildemostore unless you changed that option in the steps above).

Look for the "WebURL" output parameter.

You can read more detailed instructions on how to demo the Retail Demo Store in the Demo section at the end of this document.

Accessing Workshops

The Retail Demo Store environment is designed to provide a series of interactive workshops that progressively add functionality to the Retail Demo Store application.

The workshops are deployed in a SageMaker Jupyter environment that is deployed in your CloudFormation stack. To access the Retail Demo Store workshops after the CloudFormation stack has completed, browse to Amazon SageMaker in your AWS console, and then select "Notebook > Notebook instances" in SageMaker.

You will see a running Notebook instance. Click "Open JupyterLab" for the Retail Demo Store notebook instance.

Here you will find several workshops in a directory structure in the notebook instance. See the workshops page for details.

Developer Instructions

If you're interested in contributing enhancements, features, or fixes to the Retail Demo Store, please see the Deployment Instructions for details on how to setup your local environment and deployment environment.

Delivering a Demo of the Retail Demo Store

Once you have deployed the Retail Demo Store, you may want to walk through the demonstration guide to learn how to show the features the Retail Demo Store provides.

The intent of the Retail Demo Store is to 1) provide a tool to demonstrate the capabilities of key AWS services for retail, eCommerce, and digital marketing use-cases and 2) provide a platform for individual AWS customers to step through workshops and AWS internal teams to deliver customer-facing workshops, Immersion Days, hackathons, and similar types of events.

  1. Creating a Retail Demo Store account
  2. Personalized Experience

Known Issues/Limitations

  • The application was written for demonstration and education purposes and not for production use.
  • You currently cannot deploy this project multiple times in the same AWS account and the same AWS region. However, you can deploy the project into separate supported regions within the same AWS account.
  • Make sure your CloudFormation stack name uses all lowercase letters.
  • Currently only tested in the AWS regions provided in the deployment instructions above. The only limitation for deploying into other regions is availability of all required services.
    • Amazon IVS is currently only supported in the N. Virginia (us-east-1), Oregon (us-west-2), and Ireland (eu-west-1) regions. Therefore, to deploy the Retail Demo Store in a region that does not support IVS, be sure to select to use the Default IVS Streams CloudFormation template parameter.

Troubleshooting - FAQs

Q: When accessing the Retail Demo Store web application after deploying the project, a CloudFront error is displayed. What's wrong?

A: Sign in to the AWS account/region where the project was deployed and browse to CodePipeline. Verify that the pipeline with "WebUIPipeline" in the name has successfully been built. If it failed, inspect the details of the Build stage to diagnose the root cause.

Q: When accessing the Retail Demo Store web application after deploying the project, the home page shows spinning icons and products are never loaded. What's wrong?

A: The most likely cause is an error building or deploying one or more of the microservices. Sign in to the AWS account/region where the project was deployed and browse to CodePipeline. Verify that all of the Retail Demo Store pipelines have completed successfully. Inspect the details for any that have failed to determine the root cause. Sometimes just manually triggering a build/deploy will resolve the issue.

Q: This project is expensive to run (or keep running). How can I reduce the running cost of a deployment?

A: The most costly service in the project for an idle deployment is Amazon Personalize. You can eliminate Personalize idle costs by stopping all Amazon Personalize recommenders and deleting all campaigns in the Retail Demo Store dataset group for Personalize. This just shuts down the real-time inference endpoints; the datasets and ML models will remain. You should also change all of the recommender and campaign ARN parameter values in the AWS Systems Manager Parameter Store to NONE, leaving the parameter values for filters and the event tracker alone. These parameter names start with /retaildemostore/personalize/ (e.g., /retaildemostore/personalize/recommended-for-you-arn). Once you complete these steps, the storefront will fall back to default behavior for recommending products from the catalog. To reactive Personalize, start the recommenders and create campaigns and then set the recommender and/or campaign ARNs back in the Systems Manager Parameter Store. The storefront will automatically start showing recommendations from Personalize again.

Reporting Bugs

If you encounter a bug, please create a new issue with as much detail as possible and steps for reproducing the bug. See the Contributing Guidelines for more details.

License

This sample code is made available under a modified MIT license. See the LICENSE file.

retail-demo-store's People

Contributors

adibuer-lab avatar akramdweikat avatar alexchirayath avatar amazon-auto avatar annainspace avatar bastleblanc avatar benjymoses avatar ccl19 avatar connorkirk avatar daemon-joe avatar dairiley avatar damiendaemon avatar dastra avatar dependabot[bot] avatar fahadnbs avatar gfaires avatar hawjefferson avatar ijemmy avatar james-jory avatar jbt avatar jeffpatzer avatar kazbaig avatar manbearshark avatar patrick-239 avatar pierreaws avatar ronaks4 avatar shivanimehendarge avatar sjaffari avatar svozza avatar yeeland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

retail-demo-store's Issues

Move to using Go Modules

I took a look at the Go code and the binaries are built by just doing a go get during build time. This can cause issues down the line as builds are not repeatable and versions are unknown.

Take a look at using Go modules instead

https://blog.golang.org/using-go-modules

It will pin the versions and allow the builds to be repeatable, it will also let you control when you want to bump versions of libraries being used and if a vulnerability is found in a library being used you can know if you have a bad version as well.

You'll just need to commit the go.mod and go.sum files into the repo.

Featured products on main/home view not using personalized ranking

The main/home view is displaying featured products with the Personalize badge that personalized ranking is being used but this component is just displaying the featured products directly. Reranking (like on the category pages) is not being done.

Add a call to rerank the featured products so they're personalized.

Cold item recommendations

The current user-personalization implementation in the project (i.e. "Inspired by your shopping trends" on the homepage) does not demonstrate the cold item (exploration) capabilities of the aws-user-personalization recipe. One way to add this to the project would be to tag a small number of products across various categories as "cold" in the products.yaml file and then carry this tag/field through to the products service so that the historical interactions generator can skip generating interactions for these products, the Personalize schema (CREATION_TIMESTAMP in the items dataset) and campaign settings can be initialized accordingly, and the storefront can visually denote a product as being "cold" or "new".

Utility module for workshops

Several of the workshops have code/routines that could be moved into a shared modules to improve maintainability, reusability, and streamline the workshop code.

  • Copy/port rebuild_webui_service from src/aws-lambda/personalize-pre-create-campaigns/personalize-pre-create-campaigns.py so that any workshop can trigger a rebuild and redeploy of the web-ui. For example, after updating a SSM parameter value that is used by web-ui.
  • The Experimentation workshops have similar/duplicate code for creating experiment configs, simulating experiments, calculating sample sizes, etc that could be factored into a module.
  • The Personalization workshop has a function for generating interaction history that could be moved out of the workshop and into module.

Focused/filtered catalog deployments

Add support for deploying and/or displaying products from a specific set of categories in the Retail Demo Store UX. This will allow demos to be delivered that are restricted to a type of products that are relevant to the person receiving the demo. For example, if delivering a demo to someone in the personal electronics space, restrict the deployment just to products in the appropriate categories. This could be implemented a number of ways from deployment or just in the UI at run-time (and with a Personalize dynamic filter).

Web service authz

Authn is already implemented for the web UI using Cognito. However, authz has not been added to the web services (products, carts, orders, users, recommendations, etc). For this issue, RBAC will be added to secure access to the web services.

  • Create groups in Cognito to serve as roles. For example, Users and Admins to start.
  • Add API Gateway in front of web services.
  • Configure API Gateway to use Cognito user pool for authz. Setup appropriate access controls for each REST entry point. For example, only Admins and the user owning a profile can update a user profile, cart, and order.
  • Move ELBs inside VPC to prevent direct public access to web services.
  • Configure VPC link for APIGW to allow access to ELBs from APIGW only.
  • Make necessary changes to web UI to include tokens in calls to web services.
  • Be aware of valid public REST endpoints and ensure they remain open or controlled using alternative mechanism (i.e. resource policy using IP whitelisting). For example, recommendations for partner integrations for partners such as Braze connected content.

Handle search index not existing more gracefully

Currently the Search service and UI do not handle the situation where the search index has not been created in ES (such as after a fresh deployment where ES is not auto-populated).

The Search service should return a suitable error code and the UI should trap this error and provide a more user-friendly experience.

add support for Stock management for products

The idea is to be able to integrate with external demos which would simulate physical stores, and stock could be updated via an API.

Design is probably simply a new field in the product service and an api

Add store locations and BOPUS shopping model

Add support for a store location entity, associate inventory to store location(s), integrate locations into the web UI (search by location, check inventory at location, etc), support fulfillment by pickup at location, and so on.

Update Carts service to use DynamoDB

Updates to carts are currently not being persisted to a durable datastore. This task would add DDB as the datastore back-end for carts. The products service can be used as a model.

Load notebook instance directly from GitHub

Given that the number of workshops and supporting screenshots and images has increased, we are running into the archive max size limit when initializing the workshop's CodeCommit repo. By switching from using a CodeCommit repo to directly cloning from a GitHub repo for the workshops, we avoid the limit issue. Besides, I think the current approach was being used before the project was open-sourced and publicly available for cloning into a SM instance (which is no longer the case).

The DefaultCodeRepository value on the NotebookInstance should default to the upstream repo (https://github.com/aws-samples/retail-demo-store.git) but support being overridden using the GitHubUser template parameter so developers can test changes from their fork. So something like:

DefaultCodeRepository: !Sub 'https://github.com/${GitHubUser}/retail-demo-store.git'

This will require the GitHubUser parameter to have a default of aws-samples in the root template.yaml.

Be sure to remove the steps in the root stage.sh that create and upload the retaildemostore-notebooks.zip file and verify that any notebook dependencies on the generator code and products & users data files are updated to refer to their original location in the repo. May just be the Amplitude workshop that is potentially impacted.

Ability Disable AWS Personalize

Hello,

I am trying to create a demo video with retail store demo. I have a use case where I need to showcase

  • A scenario without AWS Personalize
  • A scenario with AWS Personalize

I am using the full deployment method to enable retail demo store in AWS. I would like to find a way to disable/enable AWS personalize. This also helps reduce cost. What are my options?

Apologies I am a newbie when it comes to Personalise/Sagemaker. I don’t want to delete the solution- just control cost and do before and after video. Furthermore this allows me to learn the solution in a cost effective manner.

This is not a bug - just looking for some guidance and help on the use case.

many thanks

Need help for old version

Hello Guys,

can I get an old version of the site? because the existing S3 bucket is having a new code and a new format site. I am looking for an old format of the site.

Also, are there any step-by-step instructions to add new a product to the site for testing the DevOps life cycle?

Personalization demo fails to build

I just ran the Stackset on us-east-1, and the WebUIPipeline failed at the build stage. Apparently, the lodash npm module is missing. I see it's been added to package.json a few days ago, but it doesn't show as installed in the build logs. I don't know npm well enough to understand what the sections in packages.json mean.

For context, I ran the stackset on a clean Isengard account (my goal is to use this demo in a Personalize workshop), and while no cloudformation had any problem, I couldn't access the UI (access denied). Inspecting the stack, I saw the WebUIPipeline, and when I clicked on it, I saw a run that failed on the Build step. I'm assuming that's the cause of the problem. Here is my build log:

timestamp message
1597073784712 [Container] 2020/08/10 15:36:07 Waiting for agent ping
1597073784712 [Container] 2020/08/10 15:36:09 Waiting for DOWNLOAD_SOURCE
1597073784712 [Container] 2020/08/10 15:36:10 Phase is DOWNLOAD_SOURCE
1597073784712 [Container] 2020/08/10 15:36:10 CODEBUILD_SRC_DIR=/codebuild/output/src889395199/src
1597073784712 [Container] 2020/08/10 15:36:10 YAML location is /codebuild/output/src889395199/src/src/web-ui/buildspec.yml
1597073784712 [Container] 2020/08/10 15:36:10 No commands found for phase name: install
1597073784712 [Container] 2020/08/10 15:36:10 Processing environment variables
1597073784712 [Container] 2020/08/10 15:36:10 Decrypting parameter store environment variables
1597073784712 [Container] 2020/08/10 15:36:10 Selecting 'nodejs' runtime version '10' based on manual selections...
1597073784712 [Container] 2020/08/10 15:36:10 Running command echo "Installing Node.js version 10 ..."
1597073784712 Installing Node.js version 10 ...
1597073784712
1597073784712 [Container] 2020/08/10 15:36:10 Running command n $NODE_10_VERSION
1597073784712 installed : v10.19.0 (with npm 6.13.4)
1597073784712
1597073784712 [Container] 2020/08/10 15:36:20 Moving to directory /codebuild/output/src889395199/src
1597073784712 [Container] 2020/08/10 15:36:20 Registering with agent
1597073784712 [Container] 2020/08/10 15:36:20 Phases found in YAML: 4
1597073784712 [Container] 2020/08/10 15:36:20 BUILD: 5 commands
1597073784712 [Container] 2020/08/10 15:36:20 POST_BUILD: 4 commands
1597073784712 [Container] 2020/08/10 15:36:20 INSTALL: 0 commands
1597073784712 [Container] 2020/08/10 15:36:20 PRE_BUILD: 3 commands
1597073784712 [Container] 2020/08/10 15:36:20 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
1597073784712 [Container] 2020/08/10 15:36:20 Phase context status code: Message:
1597073784712 [Container] 2020/08/10 15:36:20 Entering phase INSTALL
1597073784712 [Container] 2020/08/10 15:36:20 Phase complete: INSTALL State: SUCCEEDED
1597073784712 [Container] 2020/08/10 15:36:20 Phase context status code: Message:
1597073784712 [Container] 2020/08/10 15:36:20 Entering phase PRE_BUILD
1597073784712 [Container] 2020/08/10 15:36:20 Running command echo Installing NPM dependencies...
1597073784712 Installing NPM dependencies...
1597073784712
1597073784712 [Container] 2020/08/10 15:36:20 Running command cd src/web-ui
1597073784712
1597073784712 [Container] 2020/08/10 15:36:20 Running command npm install
1597073784712 npm WARN lifecycle [email protected]~preinstall: cannot run in wd [email protected] npx npm-force-resolutions (wd=/codebuild/output/src889395199/src/src/web-ui)
1597073808763
1597073808763 > [email protected] install /codebuild/output/src889395199/src/src/web-ui/node_modules/yorkie
1597073808763 > node bin/install.js
1597073808763
1597073808763 CI detected, skipping Git hooks installation
1597073808763
1597073808763 > [email protected] postinstall /codebuild/output/src889395199/src/src/web-ui/node_modules/core-js
1597073808763 > node -e "try{require('./postinstall')}catch(e){}"
1597073808763
1597073808763 �[96mThank you for using core-js (�[94m https://github.com/zloirock/core-js �[96m) for polyfilling JavaScript standard library!�[0m
1597073808763
1597073808763 �[96mThe project needs your help! Please consider supporting of core-js on Open Collective or Patreon: �[0m
1597073808763 �[96m>�[94m https://opencollective.com/core-js �[0m
1597073808763 �[96m>�[94m https://www.patreon.com/zloirock �[0m
1597073808763
1597073808763 �[96mAlso, the author of core-js (�[94m https://github.com/zloirock �[96m) is looking for a good job -)�[0m
1597073808763
1597073808763
1597073808763 > [email protected] postinstall /codebuild/output/src889395199/src/src/web-ui/node_modules/ejs
1597073808763 > node ./postinstall.js
1597073808763
1597073808763 Thank you for installing �[35mEJS�[0m: built with the �[32mJake�[0m JavaScript build tool (�[32mhttps://jakejs.com/�[0m)
1597073808763
1597073808763
1597073808763 > [email protected] postinstall /codebuild/output/src889395199/src/src/web-ui/node_modules/fast-xml-parser
1597073808763 > node tasks/postinstall.js
1597073808763
1597073808763 �[96m�[1mLove fast-xml-parser? Check �[32mhttps://amitkumargupta.work �[96m�[1mfor more projects and contribution.�[0m
1597073808763
1597073810801 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/webpack-dev-server/node_modules/fsevents):
1597073810801 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
1597073810801 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/watchpack-chokidar2/node_modules/fsevents):
1597073810801 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
1597073810801 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
1597073810801 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
1597073810801
1597073810801 added 1673 packages from 1345 contributors and audited 1677 packages in 27.869s
1597073810801
1597073810801 46 packages are looking for funding
1597073810801 run npm fund for details
1597073810801
1597073810801 found 6 high severity vulnerabilities
1597073810801 run npm audit fix to fix them, or npm audit for details
1597073810801
1597073810801 [Container] 2020/08/10 15:36:50 Phase complete: PRE_BUILD State: SUCCEEDED
1597073810801 [Container] 2020/08/10 15:36:50 Phase context status code: Message:
1597073810801 [Container] 2020/08/10 15:36:50 Entering phase BUILD
1597073810801 [Container] 2020/08/10 15:36:50 Running command chmod a+x ./gen_env.sh
1597073810801
1597073810801 [Container] 2020/08/10 15:36:50 Running command rm .env
1597073810801
1597073810801 [Container] 2020/08/10 15:36:50 Running command ./gen_env.sh
1597073810801
1597073810801 [Container] 2020/08/10 15:36:50 Running command cat .env
1597073810801 VUE_APP_PRODUCTS_SERVICE_DOMAIN=http://Retai-LoadB-11DYGPJ8JPZ6T-1035246880.us-east-1.elb.amazonaws.com
1597073810801 VUE_APP_PRODUCTS_SERVICE_PORT=80
1597073810801 VUE_APP_USERS_SERVICE_DOMAIN=http://Retai-LoadB-9ESFAWZ9S62E-1078856888.us-east-1.elb.amazonaws.com
1597073810801 VUE_APP_USERS_SERVICE_PORT=80
1597073810801 VUE_APP_CARTS_SERVICE_DOMAIN=http://Retai-LoadB-7P2APP8C63Z5-412475894.us-east-1.elb.amazonaws.com
1597073810801 VUE_APP_CARTS_SERVICE_PORT=80
1597073810801 VUE_APP_ORDERS_SERVICE_DOMAIN=http://Retai-LoadB-1UU45UGQPBSKB-1426193427.us-east-1.elb.amazonaws.com
1597073810801 VUE_APP_ORDERS_SERVICE_PORT=80
1597073810801 VUE_APP_RECOMMENDATIONS_SERVICE_DOMAIN=http://Retai-LoadB-OOAQW0U76ECE-618839683.us-east-1.elb.amazonaws.com
1597073810801 VUE_APP_RECOMMENDATIONS_SERVICE_PORT=80
1597073810801 VUE_APP_SEARCH_SERVICE_DOMAIN=http://Retai-LoadB-1HYTTD5RC70P7-493854681.us-east-1.elb.amazonaws.com
1597073810801 VUE_APP_SEARCH_SERVICE_PORT=80
1597073810801 VUE_APP_AWS_REGION=us-east-1
1597073810801 VUE_APP_AWS_IDENTITY_POOL_ID=us-east-1:d611aae9-985d-449f-99fb-2fced5fb76f2
1597073810801 VUE_APP_AWS_USER_POOL_ID=us-east-1_iEzajcHp0
1597073810801 VUE_APP_AWS_USER_POOL_CLIENT_ID=6c9ru1cf1r7n7gp8quh01jf8l0
1597073810801 VUE_APP_WEB_ROOT_URL=http://d2pwtxhbueegtu.cloudfront.net
1597073810801 VUE_APP_IMAGE_ROOT_URL=http://d2pwtxhbueegtu.cloudfront.net/images/
1597073810801 VUE_APP_BOT_NAME=RetailDemoStore
1597073810801 VUE_APP_BOT_ALIAS=development
1597073810801 VUE_APP_BOT_REGION=us-east-1
1597073810801 VUE_APP_PINPOINT_APP_ID=edcb61be6f894f06b366577126e19303
1597073810801 VUE_APP_PINPOINT_REGION=us-east-1
1597073810801 VUE_APP_PERSONALIZE_TRACKING_ID=***
1597073810801 VUE_APP_AMPLITUDE_API_KEY=***
1597073810801
1597073810801 [Container] 2020/08/10 15:36:50 Running command npm run build
1597073810801
1597073810801 > [email protected] build /codebuild/output/src889395199/src/src/web-ui
1597073810801 > vue-cli-service build
1597073810801
1597073812844
1597073812844 - Building for production...
1597073840896 ERROR Failed to compile with 2 errors3:37:20 PM
1597073840896
1597073840896 This dependency was not found:
1597073840896
1597073840896 * lodash in ./node_modules/@aws-amplify/analytics/lib-esm/Providers/AmazonPersonalizeProvider.js, ./node_modules/@aws-amplify/analytics/lib-esm/Providers/AmazonPersonalizeHelper/SessionInfoManager.js
1597073840896
1597073840896 To install it, you can run: npm install --save lodash
1597073840896 ERROR Build failed with errors.
1597073840896 npm ERR! code ELIFECYCLE
1597073840896 npm ERR! errno 1
1597073840896 npm ERR! [email protected] build: vue-cli-service build
1597073840896 npm ERR! Exit status 1
1597073840896 npm ERR!
1597073840896 npm ERR! Failed at the [email protected] build script.
1597073840896 npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
1597073840896
1597073840896 npm ERR! A complete log of this run can be found in:
1597073840896 npm ERR! /root/.npm/_logs/2020-08-10T15_37_20_300Z-debug.log
1597073840896
1597073840896 [Container] 2020/08/10 15:37:20 Command did not exit successfully npm run build exit status 1
1597073840896 [Container] 2020/08/10 15:37:20 Phase complete: BUILD State: FAILED
1597073840896 [Container] 2020/08/10 15:37:20 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: npm run build. Reason: exit status 1
1597073840896 [Container] 2020/08/10 15:37:20 Entering phase POST_BUILD
1597073840896 [Container] 2020/08/10 15:37:20 Running command echo Uploading to ${WEB_BUCKET_NAME}
1597073840896 Uploading to retaildemostore-base-e1p124khcs6m-clo-webuibucket-5pldu61svcjk
1597073840896
1597073840896 [Container] 2020/08/10 15:37:20 Running command aws s3 cp --recursive ./dist s3://${WEB_BUCKET_NAME}/
1597073847210
1597073847210 The user-provided path ./dist does not exist.
1597073847210
1597073847210 [Container] 2020/08/10 15:37:25 Command did not exit successfully aws s3 cp --recursive ./dist s3://${WEB_BUCKET_NAME}/ exit status 255
1597073847210 [Container] 2020/08/10 15:37:25 Phase complete: POST_BUILD State: FAILED
1597073847210 [Container] 2020/08/10 15:37:25 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: aws s3 cp --recursive ./dist s3://${WEB_BUCKET_NAME}/. Reason: exit status 255
1597073847210 [Container] 2020/08/10 15:37:25 Expanding base directory path: src/web-ui/dist
1597073847210 [Container] 2020/08/10 15:37:25 Assembling file list
1597073847210 [Container] 2020/08/10 15:37:25 Expanding src/web-ui/dist
1597073847210 [Container] 2020/08/10 15:37:25 Skipping invalid file path src/web-ui/dist
1597073847210 [Container] 2020/08/10 15:37:25 Phase complete: UPLOAD_ARTIFACTS State: FAILED
1597073847210 [Container] 2020/08/10 15:37:25 Phase context status code: CLIENT_ERROR Message: no matching base directory path found for src/web-ui/dist

serialize-javascript package vulnerability

Running npm install in the web-ui directory results in the following warning

found 1 high severity vulnerability
run npm audit fix to fix them, or npm audit for details

Running npm audit shows that it is an issue with serialize-javascript that can be resolved by running npm audit fix.

Script repitition when staging lambda artifacts

Currently every lambda function has an identical stage.sh file in ach lambda directly, as the number of lambda functions grows this will become much harder to maintain if it ever needs to be changed. We should consolidate the staging in a single script. This will probably involve changing the bundle.sh scripts to all create an output folder name that is common to all lambda functions such as dist rather than the current pattern which is to use a unique name for each function. For example:

# we change this
echo "Building Lambda deployment package"
zip ${PACKAGE_FILE} ${LAMBDA_SOURCE}
zip -gr ${PACKAGE_FILE} pinpoint-templates

# to this

echo "Building Lambda deployment package"
zip ${PACKAGE_FILE} ${LAMBDA_SOURCE}
zip -gr ${PACKAGE_FILE} dist

Sync product updates in DDB with dependent services

DDB is our source of truth for product and category data and the Products service is the interface for accessing and updating this data across the application. There are other service integrations that also work off product data including Elasticsearch for product search and Personalize for product recommendations.

The DDB products and category tables are seeded with data from the products.yaml and categories.yaml files at deployment time. For Elasticsearch, there is deployment time option to automatically index products from products.yaml or the user can choose to go step through the Search workshop. For Personalize, there is also a deployment time option to train models based on product, user, and (synthetically generated) interaction data.

This currently works well since product information is essentially read-only in the application. However, with the addition of product add, update, and delete operations, the limitations of this approach start to become problems. For example, when a new product is added, it should be automatically indexed in ES and added to the Items dataset in Personalize for cold start recommendations.

This could be solved by adding logic to the Products service to make calls to the Search and Recommendations service when products are added, updated, or deleted but this starts to more tightly couple these services. An alternative approach that is more scalable, flexible, and decoupled is to use DDB streams and Lambda functions to keep dependent services up to date with changes to products.

For Personalize, this would unlock adding some key use-cases to the project including filtering out of stock items and recommendations for cold/new items.

No navigational exit from sign in/sign up views

In the new UX, the only way out of the sign in/sign up views is the browser's back button. The old UX used to maintain the top nav to allow you to easily navigate back to other parts of the app. This makes the app more difficult to use. Consider adding an exit/cancel option or maintain the top nav.

Custom resource to delete Personalize resources

Since the Personalize resources (schemas, datasets, solutions, campaigns, event tracker) are all created outside of CloudFormation by a notebook or Lambda function, they are not cleaned up automatically when the Retail Demo Store stack is deleted. Although there is a Personalize Cleanup Notebook that can be used to delete these resources, it would be easy to miss or forget to run through this notebook before deleting the stack. Once the stack is deleted, the notebooks are deleted too. In addition, if the user initially deploying the stack chooses to have the Personalize campaigns auto-created post-deployment, it's not apparent that the cleanup notebook should be run. This could leave behind resources that will continue to incur unexpected charges.

To ensure that Personalize resources created as part of the Retail Demo Store deployment are cleaned up when the stack is deleted, a custom resource should be created that deletes these resources.

What is the difference between _userauth.sign_in vs. UserSignedIn?

Just wondering what is the difference between the following events

_userauth.sign_in vs. UserSignedIn - same goes for 3 __userauth.sign_up and _userauth.sign_out. Also to add what is the naming convention for Pinpoint Events to choose if I were to add more events. So far I have seen the following

_userauth.sign_in (new and duplicate)
Purchase event (extra space and e is not capitalised)
UserSignedIn (more common with other events)

Here is a quick view of all the events under pinpoint campaign screen.
Screen Shot 2021-02-10 at 7 48 02 am

IVS product mappings are broken/missing

When the new products and categories were introduced in #159, the products added for the IVS integration (#96) were lost. This broke the product mapping file that maps products being demonstrated in the video stream with products being displayed and recommended on the live stream view.

The products added by the IVS PR need to be added back to the products.yaml file and the videos mapping file needs to be updated with the new product IDs.

Update Orders service to use DynamoDB

Updates to orders are currently not being persisted to a durable datastore. This task would add DDB as the datastore back-end for orders. The products service can be used as a model.

Build conversational AI workshop notebook

The current Lex bot integration on the Help view (accessed from "?" icon in top nav) will load the chat bot widget if there is a Lex bot configured on the backend. Otherwise, a message is displayed indicating that it's not fully configured.

Building out the chatbot experience would make for a useful workshop. For this issue, a workshop notebook should be created that walks the user/developer through building a chatbot in Lex that provides retail-specific intents. Once the bot is created on the backend via the workshop, the frontend is already setup to automatically load and display the bot widget.

(BadRequestException) when calling the CreateRecommenderConfiguration operation

Hi,
I have encountered this error when running the pinpoint.create_recommender_configuration cell in the 4.1-Pinpoint.ipynb notebook.

I solved it by adding "recommenders" to the SourceArn when authorizing Amazon Pinpoint to invoke the function.

I think the file below needs to be edited accordingly:
https://github.com/aws-samples/retail-demo-store/blob/master/aws/cloudformation-templates/services/pinpoint-personalize.yaml

SourceArn: !Sub 'arn:aws:mobiletargeting:${AWS::Region}:${AWS::AccountId}:recommenders/*'

Improve CI/CD automation

After each commit on master, each regional s3 bucket should be updated.

  • run stage.sh for each bucket, currently us-west-2, us-east-1 and eu-west-1
  • notify of the deployment / alerts in case of failure to the team.

A live version of the demo could be also updated at the same time.

Build Amazon Connect Module

Allow users to speak to an agent (chatbot). Showcase how a data dip works and the data flow in customising a customer experience.

Issue with np.random.choice in Personalize Workshop

Hi, I found a small error during the Create "User-Items Interactions Dataset" in 1.1-Personalize notebook.

During interaction simulation you define:

category = np.random.choice(preferred_categories, 1, p=[0.6, 0.25, 0.15])[0]

This generate an error because preferred_categories only have 2 items in the array and p= 3 slices fails.

Is there a way to collect pinpoint event data from a plain HTML file e.g. via CDN include?

Feedback from a customer meeting (with an existing ecommerce site) who wants to use pinpoint for abandon cart. It seems we need to use AWS Amplify/React/Vue to integrate pinpoint. Is there any documented approach to integrate pinpoint with a vanilla - plain HTML file - e.g. via CDN/Script SRC?

I did come across some discussion/hack in AWS amplify issues in github - but nothing officially documented or best practice. I hope I have explained the problem correctly, keen to hear others experience/ways others have resolved it.

Update Users service to use DynamoDB

Updates to users are currently not being persisted to a durable datastore. This task would add DDB as the datastore back-end for users. The products service can be used as a model.

Incorrect copy destination in CopyImagesLambdaFunction

I recently set up a deployment of the retail demo store using my own staging s3 buckets via the stage.sh script.
While the solution was deployed successfully, I am unable to see the images on the website.
On further researching, it seems that there is a bug in the CopyImagesLambdaFunction code.
The lambda function copies the files under ${RootURL}/${ResourceBucketRelativePath}images/ whereas the website is looking for the data under ${RootURL}/images/

Proposed solution:
The target object keys for the images needs to be updated to store in the root directory itself.
Change the logic in the lambda function would probably be [here](The target object keys for the images needs to be updated to store in the root directory itself.)

ADMIN Intergration

Hello,

The Store code if only for front end users ? i dont see anything for tracking order for admins ?

Add task auto-scaling to services

Add ECS task auto scaling policy to services to allow them to scale in/out based on CPU. The purpose of this task is to demonstrate how auto-scaling can be configured in the deployment of services to support changes in traffic and load (i.e. Flash sale).

This task would also add practical value to workshops such as the Experimentation workshops that add spikes in load against the recommendations and products services while simulating experiments. Auto-scaling should help improve performance of experiment simulations.

Issues with product recommendations in the demo app

I had observed the following issues when using the demo app in our company.

Upon deploying the stack of retail demo store, evaluate the products listed in the Inspired by shopping trends section and there are issues in Viewing Product Recommendations:
• When We log in as a predefined user in the demo application, Pre-defined users with each category, recommendations don’t match with the categories that were allotted.
• When we create new users and click on the new category with different items the recommendations were not changing on the home page.
Kindly let me know if there is a way to overcome these issues as well as if you could kindly check and fix the issues and make a new build available.

New user doesn't have values in attributes.

When a new user created he doesn't have any values in his profile. The main problem is missing persona as it will cause an error in python script to generate synthetic user interaction history.

Add multi-product get API to the products service

The recommendations service APIs and search feature in the web-ui (SearchItem.vue) have logic where a list of product IDs is iterated over to retrieve details for each product as part of returning results or rendering a component. This results in multiple calls to the /products/id/{id} API (one call for each product). The performance for these features could be optimized if an alternative API on the products service allowed multiple product IDs to be specified in a single request and have details for all of those products returned in the response.

For example,

/products?id=1,2,3,4

would return a list of products that includes details for products with the id of 1, 2, 3, or 4.

The DynamoDB BatchGetItem API can be used to efficiently query items for this new API.

Impacted APIs in the recommendations service include:

/recommendations
/related

Please name related created resources uniquely

Someone at my org deployed this, but didn't tear it down. Late, a different person attempted to deploy this but it failed because RetailDemoStore-users-TaskRole already exists. I would expect all of these resources to be named uniquely. Can we make that happen?

Permissions in Microservices IAM Roles Are Too Permissive

Looking at the CloudFormation for the mircroservices, I noticed that that it results in 6 IAM roles being created that all have identical permissions which span all the actions that every microservice wants to perform. This violates the principle of least privilege; each microservice should only have the permissions it requires to do its job.

My proposal is to create a roles.yaml template in the aws/cloudformation-templates/services folder that contains properly scoped IAM roles for each service, which is passed into the _template.yaml file. I am happy to do a PR for this.

Error with Pinpoint Workshop

Hi, I'm following the Workshop notebooks and while executing the "Create Pinpoint Recommender Configuration" step inside 4.1-Pinpoint notebook I receive the following error:

`---------------------------------------------------------------------------
BadRequestException Traceback (most recent call last)
in ()
15 'RecommendationProviderUri': personalize_campaign_arn,
16 'RecommendationTransformerUri': lambda_function_arn,
---> 17 'RecommendationsPerMessage': 4
18 }
19 )

~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py in _api_call(self, *args, **kwargs)
314 "%s() only accepts keyword arguments." % py_operation_name)
315 # The "self" in this scope is referring to the BaseClient.
--> 316 return self._make_api_call(operation_name, kwargs)
317
318 _api_call.name = str(py_operation_name)

~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py in _make_api_call(self, operation_name, api_params)
624 error_code = parsed_response.get("Error", {}).get("Code")
625 error_class = self.exceptions.from_code(error_code)
--> 626 raise error_class(parsed_response, operation_name)
627 else:
628 return parsed_response

BadRequestException: An error occurred (BadRequestException) when calling the CreateRecommenderConfiguration operation: The specified ARN 'arn:aws:lambda:us-east-1:++++++++:function:RetailDemoStorePinpointRecommender' of the lambda function isn’t valid. Check the ARN of the function and permissions in its policy.
`
Thanks in advance!

Tag load balancers with service names

There are some usability improvements that can be made to some of workshop notebooks where the load balancer DNS name is needed for a web service. To make it easier to lookup load balancers for web services in notebooks, add a tag to each web service load balancer with the service name and add permission to the SageMaker notebook instance to describe load balancers and their tags.

Refactor web UI imports to reduce bundle size

The Web UI bundle is much larger than it needs to be. This creates unnecessary latency when first loading the web app due to larger download. Most of the unnecessary bulk is from Amplify pulling in the entire AWS JS SDK (see webpack bundle analyzer report). By changing the imports in the Web UI to be more specific as to the Amplify components needed, this should reduce the AWS JS SDK components to only what's needed.

Customize ReplyTo Email Address used by Cognito for password reminder and verification code emails

Currently you need to manually modify Cognito settings so that password reminder or verification code email sender is correct. Cognito sends email from the following address :

[email protected] [email protected]

is it possible that value used here is the "pinpoint sender" email you setup during Cloudformation? Basically we are leaving the demo with customers to play around - so it's best the demo sends out email from an email familiar to customers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.