Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
2 parents 12b55ba + 5f82ba4 commit 1045675
Show file tree
Hide file tree
Showing 31 changed files with 7,221 additions and 40 deletions.
45 changes: 45 additions & 0 deletions examples/lambda/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<head>
<meta name="Momento Python Client Library Documentation" content="Python client software development kit for Momento Cache">
</head>
<img src="https://docs.momentohq.com/img/logo.svg" alt="logo" width="400"/>

[![project status](https://momentohq.github.io/standards-and-practices/badges/project-status-official.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)
[![project stability](https://momentohq.github.io/standards-and-practices/badges/project-stability-stable.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)

<br>

## Example Lambda

This directory contains an example lambda, built using AWS CDK, that performs a basic set and get operation on Momento cache.

The primary use is to provide a base for testing Momento in an AWS lambda environment. The lambda creates a Momento client, and then calls a set and get on a hard-coded key,value.

## Prerequisites

- Node version 14 or higher is required (for deploying the Cloudformation stack containing the Lambda)
- To get started with Momento you will need a Momento Auth Token. You can get one from the [Momento Console](https://console.gomomento.com). Check out the [getting started](https://docs.momentohq.com/getting-started) guide for more information on obtaining an auth token.

## Deploying the Momento Python Lambda

The source code for the CDK application lives in the `infrastructure` directory.
To build and deploy it you will first need to install the dependencies:

```bash
cd infrastructure
npm install
```

To deploy the CDK app you will need to have [configured your AWS credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html#cli-chap-authentication-precedence).

You will also need a superuser token generated from the [Momento Console](https://console.gomomento.com).

Then run:

```
export MOMENTO_AUTH_TOKEN=<YOUR_MOMENTO_AUTH_TOKEN>
npm run cdk deploy
```

The lambda does not set up a way to access itself externally, so to run it, you will have to go to `MomentoDockerLambda` in AWS Lambda and run a test.

The lambda is set up to make set and get calls for the key 'key' in the cache 'cache'. You can play around with the code by changing the `docker/lambda/index.py` file. Remember to update `docker/lambda/aws_requirements.txt` file if you add additional Python dependencies.
14 changes: 14 additions & 0 deletions examples/lambda/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM --platform=linux/amd64 public.ecr.aws/lambda/python:3.8

WORKDIR /var/task

# Copy the lambda and the requirements file
COPY lambda/index.py .
COPY lambda/aws_requirements.txt .

# Install Python dependencies
RUN pip install -r aws_requirements.txt -t .

# Set the CMD to your lambda (could also be done as a parameter override outside of the Dockerfile)
CMD ["index.handler"]

1 change: 1 addition & 0 deletions examples/lambda/docker/lambda/aws_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
momento==1.7.1
36 changes: 36 additions & 0 deletions examples/lambda/docker/lambda/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from datetime import timedelta

from momento import CacheClient, Configurations, CredentialProvider
from momento.responses import CacheGet, CacheSet, CreateCache


def handler(event, lambda_context):
cache_name = "default-cache"
with CacheClient(
configuration=Configurations.Laptop.v1(),
credential_provider=CredentialProvider.from_environment_variable("MOMENTO_AUTH_TOKEN"),
default_ttl=timedelta(seconds=60),
) as cache_client:
create_cache_response = cache_client.create_cache(cache_name)

if isinstance(create_cache_response, CreateCache.CacheAlreadyExists):
print(f"Cache with name: {cache_name} already exists.")
elif isinstance(create_cache_response, CreateCache.Error):
raise create_cache_response.inner_exception

print("Setting Key: key to Value: value")
set_response = cache_client.set(cache_name, "key", "value")

if isinstance(set_response, CacheSet.Error):
raise set_response.inner_exception

print("Getting Key: key")
get_response = cache_client.get(cache_name, "key")

if isinstance(get_response, CacheGet.Hit):
print(f"Look up resulted in a hit: {get_response}")
print(f"Looked up Value: {get_response.value_string!r}")
elif isinstance(get_response, CacheGet.Miss):
print("Look up resulted in a: miss. This is unexpected.")
elif isinstance(get_response, CacheGet.Error):
raise get_response.inner_exception
3 changes: 3 additions & 0 deletions examples/lambda/infrastructure/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
**/*.d.ts
62 changes: 62 additions & 0 deletions examples/lambda/infrastructure/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"root": true,
"env": {
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:import/recommended",
"plugin:prettier/recommended",
"plugin:node/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"project": "./tsconfig.json"
},
"plugins": ["@typescript-eslint"],
"rules": {
"semi": ["error", "always"],
"import/no-extraneous-dependencies": ["error", {}],
"node/no-unsupported-features/es-syntax": "off",
"node/no-missing-import": [
"error",
{
"tryExtensions": [".js", ".ts", ".json", ".node"]
}
],
"prettier/prettier": "error",
"block-scoped-var": "error",
"eqeqeq": "error",
"no-var": "error",
"prefer-const": "error",
"eol-last": "error",
"prefer-arrow-callback": "error",
"no-trailing-spaces": "error",
"quotes": ["warn", "single", {"avoidEscape": true}],
"no-restricted-properties": [
"error",
{
"object": "describe",
"property": "only"
},
{
"object": "it",
"property": "only"
}
],
// async without await is often an error and in other uses it obfuscates
// the intent of the developer. Functions are async when they want to await.
"require-await": "error",
"import/no-duplicates": "error"
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
}
8 changes: 8 additions & 0 deletions examples/lambda/infrastructure/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.js
!jest.config.js
*.d.ts
node_modules

# CDK asset staging directory
.cdk.staging
cdk.out
6 changes: 6 additions & 0 deletions examples/lambda/infrastructure/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.ts
!*.d.ts

# CDK asset staging directory
.cdk.staging
cdk.out
8 changes: 8 additions & 0 deletions examples/lambda/infrastructure/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"bracketSpacing": false,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "avoid",
"printWidth": 120
}

16 changes: 16 additions & 0 deletions examples/lambda/infrastructure/bin/infrastructure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { App } from "aws-cdk-lib";
import {MomentoLambdaStack} from "../lib/stack";

const app = new App();
new MomentoLambdaStack(app, 'MomentoPythonLambda', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */
/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});
44 changes: 44 additions & 0 deletions examples/lambda/infrastructure/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"app": "npx ts-node --prefer-ts-exts bin/infrastructure.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false
}
}
Empty file.
8 changes: 8 additions & 0 deletions examples/lambda/infrastructure/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/test'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
};
25 changes: 25 additions & 0 deletions examples/lambda/infrastructure/lib/stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as path from 'path';
import * as cdk from 'aws-cdk-lib';
import {Construct} from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class MomentoLambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

if (!process.env.MOMENTO_AUTH_TOKEN) {
throw new Error('The environment variable MOMENTO_AUTH_TOKEN must be set.');
}

// Create Lambda function from Docker Image
const dockerLambda = new lambda.DockerImageFunction(this, 'MomentoDockerLambda', {
functionName: 'MomentoDockerLambda',
code: lambda.DockerImageCode.fromImageAsset(path.join(__dirname, '../../docker')), // Point to the root since Dockerfile should be there
environment: {
MOMENTO_AUTH_TOKEN: process.env.MOMENTO_AUTH_TOKEN || ''
},
memorySize: 128,
timeout: cdk.Duration.seconds(30)
});
}
}
Loading

0 comments on commit 1045675

Please sign in to comment.