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

add gen ai rag example #231

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Empty file.
Empty file.
71 changes: 71 additions & 0 deletions cdk/examples/generative_ai_rag/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from distutils import util

from aws_cdk import App, Environment
from components.core_infrastructure_construct import CoreInfrastructureProps
from core_infra.lib.core_infra_stack import CoreInfraStack
from dotenv import dotenv_values
from lib.gen_ai_rag_stack import GenAIRagServiceStack
from lib.gen_ai_rag_stack_props import GenAIRagServiceStackProps

from other_stack.bedrock_agent_stack import BedrockAgentStack

app = App()

env_config = dotenv_values(".env")

deploy_core = bool(util.strtobool(env_config["deploy_core_stack"]))
deploy_bedrock = bool(util.strtobool(env_config.pop("deploy_bedrock_agent")))

if deploy_bedrock:
BedrockAgentStack(
app,
"BedrockAgentStack",
env=Environment(
account=env_config["account_number"],
region=env_config["aws_region"],
),
)

gen_ai_rag_stack_props = GenAIRagServiceStackProps(**env_config)

if deploy_core:
core_config = {
i
for i in list(env_config.items())
if i[0] in CoreInfrastructureProps().__dict__.keys()
}

core_props = CoreInfrastructureProps(**dict(core_config))
core_stack = CoreInfraStack(
app,
"CoreInfraStack",
core_infra_props=core_props,
env=Environment(
account=core_props.account_number,
region=core_props.aws_region,
),
)
gen_ai_rag_stack_props.vpc = core_stack.vpc
gen_ai_rag_stack_props.ecs_cluster_name = core_stack.ecs_cluster_name
namespaces = [
ns
for ns in core_stack.private_dns_namespaces
if ns.namespace_name == gen_ai_rag_stack_props.namespace_name
][0]

gen_ai_rag_stack_props.ecs_task_execution_role_arn = core_stack.ecs_task_execution_role_arn


gen_ai_rag_service_stack = GenAIRagServiceStack(
app,
"GenAIRAGService",
gen_ai_rag_stack_props,
env=Environment(
account=gen_ai_rag_stack_props.account_number,
region=gen_ai_rag_stack_props.aws_region,
),
)

gen_ai_rag_service_stack.validate_stack_props()

app.synth()
60 changes: 60 additions & 0 deletions cdk/examples/generative_ai_rag/assets/action-group.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
openapi: 3.0.0
info:
title: Bookmark API
version: 1.0.0
description: bookmark actions
paths:
/bookmark/:
post:
summary: Create a new bookmark
description: Add a new bookmark with session information
operationId: putBookmark
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- sessionCode
- sessionDescription
- sessionTitle
properties:
sessionCode:
type: string
description: Unique code for the session
sessionDescription:
type: string
description: Description of the session
sessionTitle:
type: string
description: Title of the session
responses:
'201':
description: Bookmark created successfully
'400':
description: Invalid input
'500':
description: Server error
get:
summary: Get all bookmarks
description: Retrieve the list of all bookmarks
operationId: getBookmark
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: array
items:
type: object
properties:
sessionCode:
type: string
sessionDescription:
type: string
sessionTitle:
type: string
'500':
description: Server error
2,913 changes: 2,913 additions & 0 deletions cdk/examples/generative_ai_rag/assets/reinvent.txt

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions cdk/examples/generative_ai_rag/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"app": "PYTHONPATH=../ python3 app.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/__init__.py",
"**/__pycache__",
"tests"
]
},
"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,
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
"@aws-cdk/aws-redshift:columnId": true,
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
"@aws-cdk/aws-kms:aliasNameRef": true,
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
"@aws-cdk/aws-stepfunctions-tasks:ecsReduceRunTaskPermissions": true
}
}
103 changes: 103 additions & 0 deletions cdk/examples/generative_ai_rag/lambda/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import json
import boto3
import os
from botocore.exceptions import ClientError

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ['TABLE_NAME'])

def lambda_handler(event, context):
print(f"Received event: {event}")
print(f"Received context: {context}")

agent = event['agent']
action_group = event['actionGroup']
api_path = event['apiPath']
http_method = event['httpMethod']

function = determine_function(api_path, http_method)
message = execute_function(function, event)

response_body = create_response_body(message)
action_response = create_action_response(action_group, api_path, http_method, response_body)
function_response = create_function_response(action_response, event['messageVersion'])

print(f"Response: {function_response}")
return function_response

def determine_function(api_path, http_method):
if api_path == '/bookmark/' and http_method == 'POST':
return 'register-bookmark'
elif api_path == '/bookmark/' and http_method == 'GET':
return 'get-bookmark'
else:
return 'unknown'

def execute_function(function, event):
if function == 'register-bookmark':
return register_bookmark(event)
elif function == 'get-bookmark':
return get_bookmarks()
else:
return f"Unknown function: {function}"

def register_bookmark(event):
try:
request_body = event.get('requestBody', {})
properties = request_body.get('content', {}).get('application/json', {}).get('properties', [])

params = {prop['name']: prop['value'] for prop in properties if 'name' in prop and 'value' in prop}

session_code = params.get('sessionCode')
session_title = params.get('sessionTitle')
session_description = params.get('sessionDescription')

print(f"Received sessionCode: {session_code}")
print(f"Received sessionTitle: {session_title}")
print(f"Received sessionDescription: {session_description}")

if not session_code:
return "Session code is required."

table.put_item(
Item={
'sessionCode': session_code,
'sessionTitle': session_title,
'sessionDescription': session_description
}
)
return "Bookmark has been successfully registered!"
except ClientError as e:
print(e.response['Error']['Message'])
return "Failed to add bookmark."

def get_bookmarks():
try:
response = table.scan()
items = response.get('Items', [])
return json.dumps(items)
except ClientError as e:
print(e.response['Error']['Message'])
return "Failed to retrieve bookmarks."

def create_response_body(message):
return {
"TEXT": {
"body": message
}
}

def create_action_response(action_group, api_path, http_method, response_body):
return {
'actionGroup': action_group,
'apiPath': api_path,
'httpMethod': http_method,
'httpStatusCode': 200,
'responseBody': response_body
}

def create_function_response(action_response, message_version):
return {
'response': action_response,
'messageVersion': message_version
}
Empty file.
Loading
Loading