Skip to content

Add direct AWS Lambda deployment without Chalice dependency#5

Open
Copilot wants to merge 7 commits intomainfrom
copilot/create-aws-zip-file-version
Open

Add direct AWS Lambda deployment without Chalice dependency#5
Copilot wants to merge 7 commits intomainfrom
copilot/create-aws-zip-file-version

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 11, 2026

Enables deployment to AWS Lambda via zip file upload, removing the Chalice requirement for external users. The existing Chalice deployment path remains unchanged for internal use.

Changes

  • lambda_function.py: Standalone handler with proper error codes (400 for client errors, 500 for server errors)
  • .github/workflows/build-deployment-zip.yaml: Auto-generates deployment.zip on releases, uploadable as artifact or release asset
  • build-deployment-zip.sh: Local build script for customization scenarios
  • DEPLOYMENT.md: Complete deployment guide covering IAM setup, S3 configuration, and troubleshooting
  • README.md: Restructured to show both deployment options upfront
  • deployment.zip: Pre-built deployment package (~40MB) committed to the repo for immediate testing

Deployment Package Structure

deployment.zip (~40MB)
├── lambda_function.py
├── chalicelib/
│   ├── __init__.py
│   └── ytb_api_utils.py
└── [dependencies]/
    ├── boto3/
    ├── google-api-python-client/
    └── ...

Dependencies installed: boto3, google-api-python-client, google-auth, google-auth-oauthlib, google-auth-httplib2

Notably excluded: chalice (only needed for the Chalice deployment path)

Usage

Download deployment.zip directly from the repo or from the Releases page → upload to Lambda console → configure IAM/S3 → done. See DEPLOYMENT.md for details on IAM policies and S3 token storage.

Original prompt

This section details on the original issue you should resolve

<issue_title>Create version that can be directly uploaded to AWS as a zip file</issue_title>
<issue_description>I.e., without chalice dependency. Just the normal process.

https://github.com/ACC-HelloWorld/5-data-logging#aws-lambda-function

AccelerationConsortium/ac-dev-lab#231
AccelerationConsortium/ac-dev-lab#271

https://docs.aws.amazon.com/lambda/latest/dg/python-package.html

copying some code from the notebook mentioned in https://github.com/ACC-HelloWorld/5-data-logging#aws-lambda-function

# -*- coding: utf-8 -*-
"""1.5.2-mongodb-aws-lambda-prep.ipynb

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/github/AccelerationConsortium/ac-microcourses/blob/main/docs/courses/hello-world/1.5.2-mongodb-aws-lambda-prep.ipynb

# Preparing the Python code and dependencies for AWS Lambda

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/AccelerationConsortium/ac-microcourses/blob/main/docs/courses/hello-world/1.5.2-mongodb-aws-lambda-prep.ipynb)

For simplicity, we'll package `pymongo`, our Python dependency, along with our `lambda_function.py` script per the [guidelines in the AWS docs](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html). See also the [How to Use PyMongo to Connect MongoDB Atlas with AWS Lambda](https://www.mongodb.com/developer/products/atlas/awslambda-pymongo/) MongoDB tutorial and the [Manage Connections with AWS Lambda](https://www.mongodb.com/docs/atlas/manage-connections-aws-lambda/) MongoDB documentation page. This notebook is intended to be run on Google Colab.
"""

# Commented out IPython magic to ensure Python compatibility.
# %mkdir dependencies

# Commented out IPython magic to ensure Python compatibility.
# %pip install --target ./dependencies pymongo

# Commented out IPython magic to ensure Python compatibility.
# %%writefile lambda_function.py
# import os
# import json
# from pymongo import MongoClient
# 
# atlas_uri = os.environ['ATLAS_URI']
# client = MongoClient(atlas_uri)
# 
# def lambda_handler(event, context):
#     try:
#         payload = json.loads(event["body"])
#         document = payload["document"]
#         db_name = payload["database"]
#         collection_name = payload["collection"]
#         db = client[db_name]
#         collection = db[collection_name]
#         result = collection.insert_one(document)
#         return {
#             "statusCode": 200,
#             "body": json.dumps({"message": "Document inserted successfully"}),
#         }
#     except Exception as e:
#         return {
#             "statusCode": 500,
#             "body": json.dumps({"error": str(e)}),
#         }
#

# Commented out IPython magic to ensure Python compatibility.
# %cd dependencies
!zip -r ../deployment.zip *
# %cd ..
!zip deployment.zip lambda_function.py

"""Download the file:"""

import sys

if 'google.colab' in sys.modules:
    from google.colab import files
    files.download('deployment.zip')

"""NOTE: If the above cell doesn't work in Google Colab, you can download `deployment.zip` using the left navigation bar by **hovering over the file**, clicking the three vertical dots, and clicking "download", as shown below. If you don't see the file, you may need to click the refresh icon near the top of the sidebar. You will then upload this `.zip` file to AWS Lambda.
"""

In our case, we don't need to package pymongo. However, we do need the dependencies in https://github.com/AccelerationConsortium/streamingLambda/blob/main/requirements.txt, except for chalice. Write a GitHub action that automatically creates a new deployment.zip for new release versions.

Keep in mind the dependency file within chalicelib/ folder.

The main overall goal is for people outside the AC organization to be able to easily and quickly create a lambda function for their own organization/research group/etc.

See also https://ac-training-lab.readthedocs.io/en/latest/devices/picam.html, which is sort of the entry point. The whole goal is to get a new, fully functioning LAMBDA_FUNCTION_URL (which also means dealing with the YouTube token.pickle and S3)</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@sgbaird
Copy link
Copy Markdown
Member

sgbaird commented Feb 11, 2026

cc @seth-leavitt

Copilot AI and others added 5 commits February 11, 2026 18:21
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Copilot AI changed the title [WIP] Create version for AWS upload as zip file without chalice Add direct AWS Lambda deployment without Chalice dependency Feb 11, 2026
Copilot AI requested a review from sgbaird February 11, 2026 18:29
@sgbaird sgbaird marked this pull request as ready for review February 26, 2026 06:33
Copilot AI review requested due to automatic review settings February 26, 2026 06:33
@sgbaird
Copy link
Copy Markdown
Member

sgbaird commented Feb 26, 2026

@seth-leavitt, if you're still running into issues with the BYU AWS, you could test it out on a personal AWS account while we're sorting things out. I haven't tested these instructions yet, but the hope is that these instructions will provide some additional clarity once we refine it

@sgbaird
Copy link
Copy Markdown
Member

sgbaird commented Feb 26, 2026

@copilot create and commit a deployment.zip for me so that we can test it out.

Co-authored-by: sgbaird <45469701+sgbaird@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 26, 2026

@copilot create and commit a deployment.zip for me so that we can test it out.

Built and committed deployment.zip (40MB) in a264ebf. It contains lambda_function.py, chalicelib/, and all dependencies (boto3, google-api-python-client, google-auth, google-auth-oauthlib, google-auth-httplib2). You can download it directly from the branch and upload it to AWS Lambda.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enables direct AWS Lambda deployment without requiring Chalice, making it easier for external users to deploy their own YouTube streaming Lambda functions. The PR maintains backward compatibility by keeping the existing Chalice deployment path (app.py) unchanged while adding a new direct deployment option via lambda_function.py.

Changes:

  • Adds standalone lambda_function.py with improved error handling (400 for client errors, 500 for server errors) compared to the Chalice version
  • Implements automated deployment package creation via GitHub Actions workflow and local build script
  • Provides comprehensive deployment documentation with step-by-step AWS setup instructions

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
lambda_function.py New standalone Lambda handler that duplicates app.py logic but with improved error handling
build-deployment-zip.sh Local build script for creating deployment.zip with all dependencies except Chalice
.github/workflows/build-deployment-zip.yaml Automated workflow to build and attach deployment.zip to releases
DEPLOYMENT.md Comprehensive 361-line deployment guide covering IAM, S3, Lambda setup, and troubleshooting
README.md Restructured to present both deployment options with clear guidance on which to use
.gitignore Adds deployment.zip and dependencies/ to ignored files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +207 to +214
-d '{
"body": {
"action": "create",
"cam_name": "Camera1",
"workflow_name": "MyWorkflow",
"privacy_status": "private"
}
}'
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The curl example for testing via Function URL appears to have incorrect nesting. When using Lambda Function URLs, the HTTP request body is automatically placed in event['body'] as a string. The curl command should send the payload directly without wrapping it in another 'body' key. The correct format should be:

curl -X POST https://YOUR-FUNCTION-URL/ -H "Content-Type: application/json" -d '{"action": "create", "cam_name": "Camera1", "workflow_name": "MyWorkflow", "privacy_status": "private"}'

The current example would result in event['body'] containing '{"body": {...}}', which would then be parsed to {"body": {...}}, causing the code to look for payload.get("action") in the wrong nested structure.

Suggested change
-d '{
"body": {
"action": "create",
"cam_name": "Camera1",
"workflow_name": "MyWorkflow",
"privacy_status": "private"
}
}'
-d '{"action": "create", "cam_name": "Camera1", "workflow_name": "MyWorkflow", "privacy_status": "private"}'

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +27
"""
AWS Lambda handler function for YouTube streaming management.

This function can be directly deployed to AWS Lambda without Chalice.

Expected event payload:
{
"body": {
"action": "create" or "end",
"cam_name": "camera name",
"workflow_name": "workflow identifier",
"privacy_status": "public", "private", or "unlisted" (optional, default: "private")
}
}
"""
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring shows the event payload with body as a dict, but the code also handles body as a JSON string (lines 31-32), which is what Lambda Function URLs provide. Consider updating the docstring to mention both formats:

  • For Lambda Function URLs: body is a JSON string that gets parsed
  • For direct invocation/testing: body can be a dict

This would help users understand the different invocation methods.

Copilot uses AI. Check for mistakes.
1. Download and extract `deployment.zip`
2. Edit `chalicelib/ytb_api_utils.py`:
```python
# Lines 9-13
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line reference "Lines 9-13" is slightly inaccurate. The constants are on lines 9 (CHANNEL_ID), 12 (S3_BUCKET), and 13 (S3_KEY) in ytb_api_utils.py, not consecutively on lines 9-13. Consider updating to "Lines 9, 12-13" for accuracy.

Suggested change
# Lines 9-13
# Lines 9, 12-13

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +42
cam_name = payload.get("cam_name", "UnknownCam")
workflow_name = payload.get("workflow_name", "UnknownWorkflow")
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation states that workflow_name is "required", but the code provides a default value of "UnknownWorkflow" when it's missing. This is inconsistent. Either the parameter should be truly required (raising an error when missing), or the documentation should indicate it's optional with a default. Given that workflow_name is used to identify and manage specific broadcasts, it should likely be required to avoid confusion from multiple workflows sharing the default name.

Copilot uses AI. Check for mistakes.
google-auth-httplib2

# Copy lambda function and chalicelib
echo "Copying lambda function and chalicelib..."
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script should verify that required files (lambda_function.py and chalicelib/) exist before attempting to copy them. If these files are missing, the script will fail with unclear error messages. Consider adding validation checks before the copy operations to provide clearer error messages to users.

Suggested change
echo "Copying lambda function and chalicelib..."
echo "Copying lambda function and chalicelib..."
if [ ! -f lambda_function.py ]; then
echo "Error: Required file 'lambda_function.py' not found in the current directory."
echo "Please ensure you run this script from the project root where lambda_function.py exists."
exit 1
fi
if [ ! -d chalicelib ]; then
echo "Error: Required directory 'chalicelib/' not found in the current directory."
echo "Please ensure you run this script from the project root where chalicelib/ exists."
exit 1
fi

Copilot uses AI. Check for mistakes.
@sgbaird
Copy link
Copy Markdown
Member

sgbaird commented Feb 27, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create version that can be directly uploaded to AWS as a zip file

3 participants