-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fd3d8be
commit fa4a01d
Showing
28 changed files
with
1,294 additions
and
179 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
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 |
---|---|---|
@@ -1,143 +1,32 @@ | ||
# Griptape Extension Template | ||
# Griptape AWS Extension | ||
|
||
A Github template repository for creating Griptape extensions. | ||
## Overview | ||
This extension provides several [Tools](https://docs.griptape.ai/stable/griptape-tools/) for [AWS](https://aws.amazon.com/). | ||
|
||
## Getting Started | ||
```python | ||
import boto3 | ||
|
||
Via github web page: | ||
from griptape.structures import Agent | ||
from griptape.tools import AwsS3Tool | ||
|
||
Click on `Use this template` | ||
# Initialize the AWS S3 client | ||
aws_s3_client = AwsS3Tool(session=boto3.Session(), off_prompt=True) | ||
|
||
![](https://docs.github.com/assets/cb-36544/images/help/repository/use-this-template-button.png) | ||
# Create an agent with the AWS S3 client tool | ||
agent = Agent(tools=[aws_s3_client]) | ||
|
||
|
||
Via `gh`: | ||
|
||
``` | ||
$ gh repo create griptape-extension-name -p griptape/griptape-extension-template | ||
``` | ||
|
||
## What is a Griptape Extension? | ||
|
||
Griptape Extensions can add new functionality to the [Griptape framework](https://github.com/griptape-ai/griptape), such as new Tools, Drivers, Tasks, or Structures. | ||
With extensions, you can integrate custom APIs, tools, and services into the Griptape ecosystem. | ||
|
||
This repository provides a recommended structure for organizing your extension code, as well as helpful tools for testing and development. | ||
|
||
## Extension Structure | ||
|
||
The template repository is structured as follows: | ||
|
||
```bash | ||
tree -I __init__.py -I __pycache__ | ||
|
||
├── griptape | ||
│ └── extension_name # Name whatever you want | ||
│ └── tools | ||
│ └── reverse_string | ||
│ └── tool.py | ||
...more directories for other interfaces (drivers, tasks, structures, etc)... | ||
└── tests | ||
└── unit | ||
└── tools | ||
└── test_reverse_string_tool.py | ||
├── examples | ||
└── tools | ||
└── example_agent.py # Example usage of the extension | ||
├── LICENSE # Choose the appropriate license | ||
├── Makefile # Contains useful commands for development | ||
├── pyproject.toml # Contains the project's metadata | ||
├── README.md # Describes the extension and how to use it | ||
``` | ||
|
||
## Development | ||
|
||
### Poetry | ||
|
||
This project uses [Poetry](https://python-poetry.org/) for dependency management. | ||
It is recommended to configure Poetry to use [in-project](https://python-poetry.org/docs/configuration/#virtualenvsin-project) virtual environments: | ||
|
||
```bash | ||
poetry config virtualenvs.in-project true | ||
``` | ||
|
||
This will create a `.venv` directory in the project root, where the virtual environment will be stored. | ||
This ensures that the virtual environment is always in the same location, regardless of where the project is cloned. | ||
|
||
### Useful Commands | ||
|
||
#### Installing Dependencies | ||
|
||
```bash | ||
make install | ||
# Task to list all the AWS S3 buckets | ||
agent.run("List all my S3 buckets.") | ||
``` | ||
|
||
#### Running Tests | ||
## Installation | ||
|
||
Poetry: | ||
```bash | ||
make test | ||
poetry add https://github.com/griptape-ai/griptape-aws.git | ||
``` | ||
|
||
#### Running Checks (linting, formatting, etc) | ||
|
||
```bash | ||
make check | ||
``` | ||
|
||
#### Running Formatter | ||
|
||
```bash | ||
make format | ||
``` | ||
|
||
#### Running Example | ||
|
||
This template includes an [example](https://github.com/griptape-ai/tool-template/blob/main/examples/tools/example_agent.py) demonstrating how to use the extension. It shows how to import the `ReverseStringTool`, provide it to an Agent, and run it. | ||
|
||
1. Set the required environment variables. The example needs the `OPENAI_API_KEY` environment variable to be set. | ||
2. Run the example: | ||
|
||
```bash | ||
poetry run python examples/tools/example_agent.py | ||
``` | ||
|
||
If successful, you should see: | ||
``` | ||
[11/18/24 14:55:14] INFO ToolkitTask 6bb7fa5581d147b2a39e801631c98005 | ||
Input: Use the ReverseStringTool to reverse 'Griptape' | ||
[11/18/24 14:55:15] INFO Subtask c3036471831144529b8d5300c6849203 | ||
Actions: [ | ||
{ | ||
"tag": "call_VE4tGBFL7iB7VDbkKaIFIkwY", | ||
"name": "ReverseStringTool", | ||
"path": "reverse_string", | ||
"input": { | ||
"values": { | ||
"input": "Griptape" | ||
} | ||
} | ||
} | ||
] | ||
INFO Subtask c3036471831144529b8d5300c6849203 | ||
Response: epatpirG | ||
[11/18/24 14:55:16] INFO ToolkitTask 6bb7fa5581d147b2a39e801631c98005 | ||
Output: The reversed string of "Griptape" is "epatpirG". | ||
``` | ||
|
||
## Installing in Other Projects | ||
|
||
Extensions are designed to be shared. Extensions are made to easily install into existing Python projects. | ||
|
||
The easiest way to include your extension into an existing project is to install directly from the repository, like so: | ||
```bash | ||
poetry add git+https://github.com/{your-org}/{your-extension-name}.git | ||
``` | ||
|
||
To install a local copy of the extension for development, run: | ||
Pip: | ||
```bash | ||
poetry add -e /path/to/your/extension | ||
pip install git+https://github.com/griptape-ai/griptape-aws.git | ||
``` | ||
|
||
Any changes made to the extension will be automatically reflected in the project without needing to reinstall it. | ||
|
||
Advanced customers may seek to publish their extensions to PyPi. Those instructions are beyond the scope of this README. |
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,13 @@ | ||
import boto3 | ||
|
||
from griptape.structures import Agent | ||
from griptape.tools import AwsIamTool | ||
|
||
# Initialize the AWS IAM client | ||
aws_iam_client = AwsIamTool(session=boto3.Session()) | ||
|
||
# Create an agent with the AWS IAM client tool | ||
agent = Agent(tools=[aws_iam_client]) | ||
|
||
# Run the agent with a high-level task | ||
agent.run("List all my IAM users") |
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,13 @@ | ||
import boto3 | ||
|
||
from griptape.structures import Agent | ||
from griptape.tools import AwsS3Tool | ||
|
||
# Initialize the AWS S3 client | ||
aws_s3_client = AwsS3Tool(session=boto3.Session(), off_prompt=True) | ||
|
||
# Create an agent with the AWS S3 client tool | ||
agent = Agent(tools=[aws_s3_client]) | ||
|
||
# Task to list all the AWS S3 buckets | ||
agent.run("List all my S3 buckets.") |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
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,7 @@ | ||
from .base_aws_tool import BaseAwsTool | ||
from .aws_cli.tool import AwsCliTool | ||
from .aws_iam.tool import AwsIamTool | ||
from .aws_pricing.tool import AwsPricingTool | ||
from .aws_s3.tool import AwsS3Tool | ||
|
||
__all__ = ["BaseAwsTool", "AwsCliTool", "AwsIamTool", "AwsPricingTool", "AwsS3Tool"] |
File renamed without changes.
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,5 @@ | ||
version: "v1" | ||
name: AWS CLI | ||
description: Tool for accessing AWS CLI v2 commands. | ||
contact_email: [email protected] | ||
legal_info_url: https://www.griptape.ai/legal |
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 @@ | ||
git+https://github.com/aws/[email protected]#egg=awscli |
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,49 @@ | ||
from griptape.artifacts import BaseArtifact, TextArtifact, ErrorArtifact | ||
from schema import Schema, Literal | ||
from griptape.utils.decorators import activity | ||
from griptape.utils import minify_json, CommandRunner | ||
from griptape.aws.tools import BaseAwsTool | ||
from attr import define, field | ||
|
||
|
||
@define | ||
class AwsCliTool(BaseAwsTool): | ||
aws_cli_policy: str = field( | ||
default="""{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}""", | ||
kw_only=True, | ||
) | ||
|
||
@property | ||
def schema_template_args(self) -> dict: | ||
return {"policy": minify_json(self.aws_cli_policy)} | ||
|
||
@activity( | ||
config={ | ||
"description": "Can be used to execute AWS CLI v2 commands limited by this policy: {{ _self.schema_template_args['policy'] }}", | ||
"schema": Schema( | ||
{ | ||
Literal( | ||
"command", description="AWS CLI v2 command starting with 'aws'" | ||
): str | ||
} | ||
), | ||
} | ||
) | ||
def execute(self, params: dict) -> BaseArtifact: | ||
command = params["values"]["command"] | ||
result = CommandRunner().run(f"AWS_PAGER='' {command} --output json") | ||
|
||
if isinstance(result, ErrorArtifact): | ||
return result | ||
else: | ||
value = result.value | ||
|
||
if value == "": | ||
final_result = "[]" | ||
else: | ||
try: | ||
final_result = minify_json(value) | ||
except Exception: | ||
final_result = value | ||
|
||
return TextArtifact(final_result) |
Empty file.
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,101 @@ | ||
from __future__ import annotations | ||
|
||
from typing import TYPE_CHECKING | ||
|
||
from attrs import define, field | ||
from schema import Literal, Schema | ||
|
||
from griptape.artifacts import ErrorArtifact, ListArtifact, TextArtifact | ||
from griptape.aws.tools import BaseAwsTool | ||
from griptape.utils.decorators import activity, lazy_property | ||
|
||
if TYPE_CHECKING: | ||
from mypy_boto3_iam import IAMClient | ||
|
||
|
||
@define | ||
class AwsIamTool(BaseAwsTool): | ||
_client: IAMClient = field( | ||
default=None, kw_only=True, alias="client", metadata={"serializable": False} | ||
) | ||
|
||
@lazy_property() | ||
def client(self) -> IAMClient: | ||
return self.session.client("iam") | ||
|
||
@activity( | ||
config={ | ||
"description": "Can be use to get a policy for an AWS IAM user.", | ||
"schema": Schema( | ||
{ | ||
Literal( | ||
"user_name", description="Username of the AWS IAM user." | ||
): str, | ||
Literal( | ||
"policy_name", | ||
description="PolicyName of the AWS IAM Policy embedded in the specified IAM user.", | ||
): str, | ||
}, | ||
), | ||
}, | ||
) | ||
def get_user_policy(self, params: dict) -> TextArtifact | ErrorArtifact: | ||
try: | ||
policy = self.client.get_user_policy( | ||
UserName=params["values"]["user_name"], | ||
PolicyName=params["values"]["policy_name"], | ||
) | ||
return TextArtifact(policy["PolicyDocument"]) | ||
except Exception as e: | ||
return ErrorArtifact(f"error returning policy document: {e}") | ||
|
||
@activity(config={"description": "Can be used to list AWS MFA Devices"}) | ||
def list_mfa_devices(self) -> ListArtifact | ErrorArtifact: | ||
try: | ||
devices = self.client.list_mfa_devices() | ||
return ListArtifact([TextArtifact(str(d)) for d in devices["MFADevices"]]) | ||
except Exception as e: | ||
return ErrorArtifact(f"error listing mfa devices: {e}") | ||
|
||
@activity( | ||
config={ | ||
"description": "Can be used to list policies for a given IAM user.", | ||
"schema": Schema( | ||
{ | ||
Literal( | ||
"user_name", | ||
description="Username of the AWS IAM user for which to list policies.", | ||
): str | ||
}, | ||
), | ||
}, | ||
) | ||
def list_user_policies(self, params: dict) -> ListArtifact | ErrorArtifact: | ||
try: | ||
policies = self.client.list_user_policies( | ||
UserName=params["values"]["user_name"] | ||
) | ||
policy_names = policies["PolicyNames"] | ||
|
||
attached_policies = self.client.list_attached_user_policies( | ||
UserName=params["values"]["user_name"] | ||
) | ||
attached_policy_names = [ | ||
p["PolicyName"] | ||
for p in attached_policies["AttachedPolicies"] | ||
if "PolicyName" in p | ||
] | ||
|
||
return ListArtifact( | ||
[TextArtifact(str(p)) for p in policy_names + attached_policy_names] | ||
) | ||
except Exception as e: | ||
return ErrorArtifact(f"error listing iam user policies: {e}") | ||
|
||
@activity(config={"description": "Can be used to list AWS IAM users."}) | ||
def list_users(self) -> ListArtifact | ErrorArtifact: | ||
try: | ||
users = self.client.list_users() | ||
return ListArtifact([TextArtifact(str(u)) for u in users["Users"]]) | ||
except Exception as e: | ||
return ErrorArtifact(f"error listing s3 users: {e}") |
Empty file.
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,5 @@ | ||
version: "v1" | ||
name: AWS Pricing Tool | ||
description: Tool for getting current pricing information from AWS. | ||
contact_email: [email protected] | ||
legal_info_url: https://www.griptape.ai/legal |
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 @@ | ||
boto3 |
Oops, something went wrong.