generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 23
[Bedrock AgentCore] Release Testing - Workflow Changes #426
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
Merged
Merged
Changes from 8 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5ce2f04
add gen ai release test workflow
liustve 3f1ed3c
inlined traffic generation to terraform file
liustve b7cdfb3
add dynamic python version
liustve 9764189
add dynamic python version
liustve 07f9a67
add dynamic python version
liustve 81de321
Merge branch 'main' into genesis-release-test-p2
liustve 82c129c
remove python versions, removed gen ai beta
liustve 3f88697
Merge branch 'genesis-release-test-p2' of https://github.com/aws-obse…
liustve 7286d11
delete cpu architecture
liustve a2c24a6
formatting
liustve File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| ## Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| ## SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| name: Python EC2 Gen AI Use Case | ||
| on: | ||
| workflow_dispatch: # be able to run the workflow on demand | ||
| push: | ||
| branches: | ||
| - genesis-release-test | ||
| workflow_call: | ||
| inputs: | ||
| caller-workflow-name: | ||
| required: true | ||
| type: string | ||
|
|
||
| cpu-architecture: | ||
| description: "Permitted values: x86_64 or arm64" | ||
| required: false | ||
| type: string | ||
| default: "x86_64" | ||
| staging-wheel-name: | ||
| required: false | ||
| default: 'aws-opentelemetry-distro' | ||
| type: string | ||
|
|
||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
|
|
||
| env: | ||
| E2E_TEST_AWS_REGION: 'us-west-2' | ||
| E2E_TEST_ACCOUNT_ID: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }} | ||
| E2E_TEST_ROLE_NAME: ${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} | ||
| ADOT_WHEEL_NAME: ${{ inputs.staging-wheel-name }} | ||
|
|
||
| METRIC_NAMESPACE: genesis | ||
| LOG_GROUP_NAME: test/genesis | ||
| TEST_RESOURCES_FOLDER: ${GITHUB_WORKSPACE} | ||
| SAMPLE_APP_ZIP: s3://aws-appsignals-sample-app-prod-us-east-1/python-genai-sample-app.zip | ||
|
|
||
| jobs: | ||
| python-ec2-adot-genai: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set Get ADOT Wheel command environment variable | ||
| run: | | ||
| if [ "${{ github.event.repository.name }}" = "aws-otel-python-instrumentation" ]; then | ||
| # Reusing the adot-main-build-staging-jar bucket to store the python wheel file | ||
| echo GET_ADOT_WHEEL_COMMAND="aws s3 cp s3://adot-main-build-staging-jar/${{ env.ADOT_WHEEL_NAME }} ./${{ env.ADOT_WHEEL_NAME }} && python3.12 -m pip install ${{ env.ADOT_WHEEL_NAME }}" >> $GITHUB_ENV | ||
| elif [ "${{ env.OTEL_SOURCE }}" == "pypi" ]; then | ||
| echo GET_ADOT_WHEEL_COMMAND="python3.12 -m pip install ${{ env.ADOT_WHEEL_NAME }}" >> $GITHUB_ENV | ||
| else | ||
| latest_release_version=$(curl -sL https://github.com/aws-observability/aws-otel-python-instrumentation/releases/latest | grep -oP '/releases/tag/v\K[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) | ||
| echo "The latest version is $latest_release_version" | ||
| echo GET_ADOT_WHEEL_COMMAND="wget -O ${{ env.ADOT_WHEEL_NAME }} https://github.com/aws-observability/aws-otel-python-instrumentation/releases/latest/download/aws_opentelemetry_distro-$latest_release_version-py3-none-any.whl \ | ||
| && python3.12 -m pip install ${{ env.ADOT_WHEEL_NAME }}" >> $GITHUB_ENV | ||
| fi | ||
|
|
||
| - name: Initiate Gradlew Daemon | ||
| uses: ./.github/workflows/actions/execute_and_retry | ||
| continue-on-error: true | ||
| with: | ||
| command: "./gradlew :validator:build" | ||
| cleanup: "./gradlew clean" | ||
| max_retry: 3 | ||
| sleep_time: 60 | ||
|
|
||
| - name: Generate testing id | ||
| run: echo TESTING_ID="${{ github.run_id }}-${{ github.run_number }}-${RANDOM}" >> $GITHUB_ENV | ||
|
|
||
| - name: Generate XRay and W3C trace ID | ||
| run: | | ||
| ID_1="$(printf '%08x' $(date +%s))" | ||
| ID_2="$(openssl rand -hex 12)" | ||
| W3C_TRACE_ID="${ID_1}${ID_2}" | ||
| XRAY_TRACE_ID="1-${ID_1}-${ID_2}" | ||
| PARENT_ID="$(openssl rand -hex 8)" | ||
| TRACE_ID_HEADER="Root=${XRAY_TRACE_ID};Parent=${PARENT_ID};Sampled=1" | ||
| echo "XRAY_TRACE_ID=${XRAY_TRACE_ID}" >> $GITHUB_ENV | ||
| echo "W3C_TRACE_ID=${W3C_TRACE_ID}" >> $GITHUB_ENV | ||
| echo "TRACE_ID_HEADER=${TRACE_ID_HEADER}" >> $GITHUB_ENV | ||
| echo "Generated XRay Trace ID: ${XRAY_TRACE_ID}" | ||
| echo "Generated W3C Trace ID: ${W3C_TRACE_ID}" | ||
| echo "Generated Trace ID Header: ${TRACE_ID_HEADER}" | ||
|
|
||
| - name: Configure AWS Credentials | ||
| uses: aws-actions/configure-aws-credentials@v4 | ||
| with: | ||
| role-to-assume: arn:aws:iam::${{ env.E2E_TEST_ACCOUNT_ID }}:role/${{ env.E2E_TEST_ROLE_NAME }} | ||
| aws-region: ${{ env.E2E_TEST_AWS_REGION }} | ||
|
|
||
| - name: Set up terraform | ||
| uses: ./.github/workflows/actions/execute_and_retry | ||
| with: | ||
| command: "wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg" | ||
| post-command: 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list | ||
| && sudo apt update && sudo apt install terraform' | ||
|
|
||
| - name: Initiate Terraform | ||
| uses: ./.github/workflows/actions/execute_and_retry | ||
| with: | ||
| command: "cd ${{ env.TEST_RESOURCES_FOLDER }}/terraform/python/ec2/adot-genai && terraform init && terraform validate" | ||
| cleanup: "rm -rf .terraform && rm -rf .terraform.lock.hcl" | ||
| max_retry: 6 | ||
|
|
||
| - name: Deploy service via terraform | ||
| working-directory: terraform/python/ec2/adot-genai | ||
| run: | | ||
| terraform apply -auto-approve \ | ||
| -var="aws_region=${{ env.E2E_TEST_AWS_REGION }}" \ | ||
| -var="test_id=${{ env.TESTING_ID }}" \ | ||
| -var="service_zip_url=${{ env.SAMPLE_APP_ZIP }}" \ | ||
| -var="trace_id=${{ env.TRACE_ID_HEADER }}" \ | ||
| -var="get_adot_wheel_command=${{ env.GET_ADOT_WHEEL_COMMAND }}" \ | ||
|
|
||
|
|
||
| - name: Get deployment info | ||
| working-directory: terraform/python/ec2/adot-genai | ||
| run: | | ||
| echo "INSTANCE_IP=$(terraform output langchain_service_public_ip)" >> $GITHUB_ENV | ||
| echo "INSTANCE_ID=$(terraform output langchain_service_instance_id)" >> $GITHUB_ENV | ||
|
|
||
| - name: Waiting 5 Minutes for Gen AI service to be ready and emit logs, traces, and metrics | ||
| run: sleep 300 | ||
|
|
||
| - name: Validate generated logs | ||
| run: ./gradlew validator:run --args='-c python/ec2/adot-genai/log-validation.yml | ||
| --testing-id ${{ env.TESTING_ID }} | ||
| --endpoint http://${{ env.INSTANCE_IP }}:8000 | ||
| --region ${{ env.E2E_TEST_AWS_REGION }} | ||
| --metric-namespace ${{ env.METRIC_NAMESPACE }} | ||
| --log-group ${{ env.LOG_GROUP_NAME }} | ||
| --service-name langchain-traceloop-app | ||
| --instance-id ${{ env.INSTANCE_ID }} | ||
| --trace-id ${{ env.W3C_TRACE_ID }}' | ||
|
|
||
| - name: Validate generated traces | ||
| if: (success() || failure()) && !cancelled() | ||
| run: ./gradlew validator:run --args='-c python/ec2/adot-genai/trace-validation.yml | ||
| --testing-id ${{ env.TESTING_ID }} | ||
| --endpoint http://${{ env.INSTANCE_IP }}:8000 | ||
| --region ${{ env.E2E_TEST_AWS_REGION }} | ||
| --metric-namespace ${{ env.METRIC_NAMESPACE }} | ||
| --service-name langchain-traceloop-app | ||
| --instance-id ${{ env.INSTANCE_ID }} | ||
| --trace-id ${{ env.XRAY_TRACE_ID }}' | ||
|
|
||
| - name: Validate generated metrics | ||
| if: (success() || failure()) && !cancelled() | ||
| run: ./gradlew validator:run --args='-c python/ec2/adot-genai/metric-validation.yml | ||
| --testing-id ${{ env.TESTING_ID }} | ||
| --endpoint http://${{ env.INSTANCE_IP }}:8000 | ||
| --region ${{ env.E2E_TEST_AWS_REGION }} | ||
| --metric-namespace ${{ env.METRIC_NAMESPACE }} | ||
| --log-group ${{ env.LOG_GROUP_NAME }} | ||
| --service-name langchain-traceloop-app | ||
| --instance-id ${{ env.INSTANCE_ID }}' | ||
|
|
||
| - name: Cleanup | ||
| if: always() | ||
| continue-on-error: true | ||
| working-directory: terraform/python/ec2/adot-genai | ||
| run: | | ||
| terraform destroy -auto-approve \ | ||
| -var="aws_region=${{ env.E2E_TEST_AWS_REGION }}" \ | ||
| -var="test_id=${{ env.TESTING_ID }}" \ | ||
| -var="service_zip_url=${{ env.SAMPLE_APP_ZIP }}" \ | ||
| -var="trace_id=${{ env.TRACE_ID_HEADER }}" \ | ||
| -var="get_adot_wheel_command=${{ env.GET_ADOT_WHEEL_COMMAND }}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| langchain | ||
| langchain-community | ||
| langchain_aws | ||
| opentelemetry-sdk | ||
| openinference-instrumentation-langchain | ||
| opentelemetry-api | ||
| opentelemetry-semantic-conventions | ||
| python-dotenv | ||
| openlit | ||
| botocore | ||
| setuptools | ||
| boto3 | ||
| aws_opentelemetry_distro | ||
| fastapi | ||
| uvicorn[standard] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| import os | ||
| from typing import Dict, List | ||
| from dotenv import load_dotenv | ||
| from fastapi import FastAPI, HTTPException | ||
| from pydantic import BaseModel | ||
| from langchain_aws import ChatBedrock | ||
| from langchain.prompts import ChatPromptTemplate | ||
| from langchain.chains import LLMChain | ||
| from opentelemetry import trace | ||
| from opentelemetry.sdk.trace import TracerProvider | ||
| from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter | ||
| from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter | ||
| from openinference.instrumentation.langchain import LangChainInstrumentor | ||
|
|
||
| # Load environment variables | ||
| load_dotenv() | ||
|
|
||
| # Set up OpenTelemetry with BOTH exporters | ||
| tracer_provider = TracerProvider() | ||
|
|
||
| # Add Console exporter | ||
| console_exporter = ConsoleSpanExporter() | ||
| console_processor = BatchSpanProcessor(console_exporter) | ||
| tracer_provider.add_span_processor(console_processor) | ||
|
|
||
| # Add OTLP exporter | ||
| otlp_exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces") | ||
| otlp_processor = BatchSpanProcessor(otlp_exporter) | ||
| tracer_provider.add_span_processor(otlp_processor) | ||
|
|
||
| # Set as global provider | ||
| trace.set_tracer_provider(tracer_provider) | ||
|
|
||
| # Instrument LangChain with OpenInference | ||
| LangChainInstrumentor().instrument(tracer_provider=tracer_provider) | ||
|
|
||
| # Initialize FastAPI app | ||
| app = FastAPI(title="LangChain Bedrock OpenInference API", version="1.0.0") | ||
|
|
||
| # Initialize the LLM with AWS Bedrock | ||
| llm = ChatBedrock( | ||
| model_id="anthropic.claude-3-haiku-20240307-v1:0", | ||
| model_kwargs={ | ||
| "temperature": 0.7, | ||
| "max_tokens": 500 | ||
| }, | ||
| region_name=os.getenv("AWS_DEFAULT_REGION", "us-west-2") | ||
| ) | ||
|
|
||
| # Create a prompt template | ||
| prompt = ChatPromptTemplate.from_template( | ||
| "You are a helpful assistant. The user says: {input}. Provide a helpful response." | ||
| ) | ||
|
|
||
| # Create a chain | ||
| chain = LLMChain(llm=llm, prompt=prompt) | ||
|
|
||
| # Request models | ||
| class ChatRequest(BaseModel): | ||
| message: str | ||
|
|
||
| class BatchChatRequest(BaseModel): | ||
| messages: List[str] | ||
|
|
||
| class ChatResponse(BaseModel): | ||
| response: str | ||
|
|
||
| class BatchChatResponse(BaseModel): | ||
| responses: List[Dict[str, str]] | ||
|
|
||
| # Sample prompts for testing | ||
| SAMPLE_PROMPTS = [ | ||
| "What is the capital of France?", | ||
| "How do I make a cup of coffee?", | ||
| "What are the benefits of exercise?", | ||
| "Explain quantum computing in simple terms", | ||
| "What's the best way to learn programming?" | ||
| ] | ||
|
|
||
| @app.get("/") | ||
| async def root(): | ||
| return { | ||
| "message": "LangChain Bedrock OpenInference API is running!", | ||
| "endpoints": { | ||
| "/ai-chat": "Single message chat endpoint", | ||
| "/hello": "Simple hello endpoint" | ||
| } | ||
| } | ||
|
|
||
| @app.post("/ai-chat", response_model=ChatResponse) | ||
| async def chat(request: ChatRequest): | ||
| """ | ||
| Chat endpoint that processes a single user message through AWS Bedrock | ||
| """ | ||
| try: | ||
| # Process the input through the chain | ||
| result = await chain.ainvoke({"input": request.message}) | ||
| return ChatResponse(response=result["text"]) | ||
| except Exception as e: | ||
| raise HTTPException(status_code=500, detail=str(e)) | ||
|
|
||
| @app.get("/health") | ||
| async def health(): | ||
| """Health check endpoint""" | ||
| return {"status": "healthy", "llm": "AWS Bedrock Claude 3 Haiku"} | ||
|
|
||
| if __name__ == "__main__": | ||
| import uvicorn | ||
| print("Starting FastAPI server with AWS Bedrock and OpenInference instrumentation...") | ||
| print("Make sure AWS credentials are configured") | ||
| print("Server will run on http://localhost:8000") | ||
| print("API docs available at http://localhost:8000/docs") | ||
|
|
||
| uvicorn.run(app, host="0.0.0.0", port=8000) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.