-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement lambda handler for deployments in AWS lambda
- Loading branch information
Showing
4 changed files
with
152 additions
and
2 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
|
@@ -19,7 +19,7 @@ jobs: | |
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Build and push Docker images | ||
- name: Build and push the base Docker image | ||
uses: docker/[email protected] | ||
with: | ||
context: . | ||
|
@@ -28,3 +28,12 @@ jobs: | |
cache-from: type=gha | ||
cache-to: type=gha,mode=max | ||
tags: ghcr.io/khaosresearch/eidos:latest,ghcr.io/khaosresearch/eidos:${{ github.event.release.tag_name }} | ||
- name: Build and push the lambda Docker image | ||
uses: docker/[email protected] | ||
with: | ||
context: . | ||
file: ./Dockerfile.lambda | ||
push: true | ||
cache-from: type=gha | ||
cache-to: type=gha,mode=max | ||
tags: ghcr.io/khaosresearch/eidos-lambda:latest,ghcr.io/khaosresearch/eidos-lambda:${{ github.event.release.tag_name }} |
This file contains 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,22 @@ | ||
FROM amazon/aws-lambda-python:3.11 | ||
|
||
# When sending request from the UI it crashes as described in this issue, this is a patch for it | ||
# https://github.com/aws/aws-lambda-runtime-interface-emulator/issues/97#issuecomment-1707171018 | ||
RUN curl -Lo /usr/local/bin/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/download/v1.10/aws-lambda-rie \ | ||
&& chmod +x /usr/local/bin/aws-lambda-rie | ||
|
||
# Install main dependency | ||
COPY pyproject.toml /tmp/eidos/pyproject.toml | ||
COPY README.md /tmp/eidos/README.md | ||
COPY src /tmp/eidos/src | ||
RUN pip install --no-cache-dir "/tmp/eidos" | ||
|
||
# Copy default functions and provide ENV to override it functions | ||
COPY ./functions /var/task/functions | ||
ENV EIDOS_FUNCTIONS_FOLDER=/var/task/functions | ||
|
||
# Copy lambda's code | ||
#COPY serverless/eidos/src/ /var/task | ||
|
||
# Setup lambda's handler | ||
CMD [ "eidos.lambda.lambda_handler" ] |
This file contains 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 |
---|---|---|
|
@@ -20,7 +20,9 @@ Or directly from GitHub: | |
pip install "eidos @ git+ssh://[email protected]/KhaosResearch/eidos.git" | ||
``` | ||
|
||
## Run | ||
## Deployment | ||
|
||
* Development | ||
|
||
Run the API with the following command: | ||
|
||
|
@@ -30,6 +32,8 @@ uvicorn eidos.api:app --host 0.0.0.0 --port 8090 --reload | |
|
||
You can override the default configuration by setting [environment variables](src/eidos/settings.py). | ||
|
||
* Docker | ||
|
||
Alternatively, you can use the provided [Dockerfile](Dockerfile) to build a Docker image and run the API in a container: | ||
|
||
```bash | ||
|
@@ -43,8 +47,30 @@ Example: | |
curl -X POST -H "Content-Type: application/json" -d '{"who": "me"}' http://localhost:8090/api/v1/execution/salute | ||
``` | ||
|
||
* Kubernetes | ||
|
||
To deploy the container in Kubernetes, a reference deployment is available and documented at [deployments](deployments/). | ||
|
||
* Serverless in AWS | ||
|
||
# Semantic search of database of documents | ||
|
||
Another docker image to deploy serverless in AWS Lambda is provided in [Dockerfile.lambda](Dockerfile.lambda). The image is based on the official AWS Lambda Python 3.11 image. For extending this image the process is the same as the main image. | ||
|
||
```console | ||
$ docker build -t eidos-lambda -f Dockerfile.lambda . | ||
``` | ||
|
||
Run the container locally with the following command or deploy in AWS Lambda as a docker container image: | ||
```bash | ||
docker run --rm -p 9001:8080 eidos-lambda | ||
``` | ||
|
||
Invoke the function for local testing with sample query | ||
```bash | ||
curl -XPOST "http://localhost:9001/2015-03-31/functions/function/invocations" -d '{"command": "EXECUTE", "parameters": {"function": "salute", "args": {"who": "me, I am executing serverless"}}}' | ||
``` | ||
|
||
## Testing | ||
|
||
`pytest` is used for testing. You can run the tests with the following command: | ||
|
This file contains 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,93 @@ | ||
from enum import Enum | ||
from typing import Any | ||
|
||
import structlog | ||
|
||
from eidos.execute import ( | ||
execute, | ||
get_function_schema, | ||
get_openai_function_definition, | ||
list_functions_names, | ||
list_functions_openai, | ||
) | ||
|
||
log = structlog.get_logger("eidos.lambda") | ||
|
||
|
||
class ValidationCommands(Enum): | ||
"""Enum to hold the different validation commands from eidos.""" | ||
|
||
LIST = "LIST" | ||
LIST_NAMES = "LIST_NAMES" | ||
GET_DEFINITION = "GET_DEFINITION" | ||
GET_SCHEMA = "GET_SCHEMA" | ||
EXECUTE = "EXECUTE" | ||
|
||
def __str__(self): | ||
return self.value | ||
|
||
def __repr__(self): | ||
return self.value | ||
|
||
|
||
def lambda_handler(event: dict[str, Any], context: dict[str, Any]): | ||
try: | ||
log.info("Processing event", command=event["command"]) | ||
command = event["command"] | ||
except KeyError: | ||
raise ValueError( | ||
f"There is a required field 'command' with the function to execute. " | ||
f"Possible values: {ValidationCommands.__members__}" | ||
) | ||
|
||
try: | ||
validation_function = ValidationCommands[command] | ||
except KeyError: | ||
raise ValueError( | ||
f"Unknown function: {event['command']}. " | ||
f"Possible values: {ValidationCommands.__members__}" | ||
) | ||
|
||
match validation_function: | ||
case ValidationCommands.LIST: | ||
return list_functions_openai() | ||
case ValidationCommands.LIST_NAMES: | ||
return list_functions_names() | ||
case ValidationCommands.GET_DEFINITION: | ||
if "function" in event.get("parameters", {}): | ||
function = event["parameters"]["function"] | ||
return get_openai_function_definition(function) | ||
else: | ||
return { | ||
"statusCode": 400, | ||
"body": "Missing function. Provide as parameters.function", | ||
} | ||
case ValidationCommands.GET_SCHEMA: | ||
if "function" in event.get("parameters", {}): | ||
function = event["parameters"]["function"] | ||
return get_function_schema(function) | ||
else: | ||
return { | ||
"statusCode": 400, | ||
"body": "Missing function. Provide as parameters.function", | ||
} | ||
case ValidationCommands.EXECUTE: | ||
if "function" in event.get("parameters", {}): | ||
function = event["parameters"]["function"] | ||
else: | ||
return { | ||
"statusCode": 400, | ||
"body": "Missing function. Provide as parameters.function", | ||
} | ||
|
||
args = event["parameters"].get("args", {}) # Default to empty parameters | ||
log.info("Executing function ", function=function, arguments=args) | ||
|
||
result = execute(function, args) | ||
|
||
return result | ||
case _: | ||
raise ValueError( | ||
f"Unknown function: {event['command']}. " | ||
f"Possible values: {ValidationCommands.__members__}" | ||
) |