|
1 | 1 | # OSBot-AWS |
2 | 2 |
|
3 | | - |
| 3 | + |
4 | 4 |
|
5 | | -Large number of AWS apis and utils from the OWASP Security Bot (OSBot) which make |
6 | | -the use of AWS's boto3 library easier and more intuitive. |
| 5 | +A comprehensive Python library for interacting with AWS services, providing simplified and type-safe wrappers around boto3. |
7 | 6 |
|
8 | | -## Current version is 2.x.x |
| 7 | +## Overview |
9 | 8 |
|
10 | | -This version has a number of breaking changes, mainly on the location of the apis, |
11 | | -since we are moving into a specific folder per service (e.g. S3, SQS, etc) |
| 9 | +OSBot-AWS is a powerful toolkit that makes working with AWS services easier and more pythonic. It provides: |
12 | 10 |
|
13 | | -### Install from PyPi |
| 11 | +- **Type-safe wrappers** around common AWS services |
| 12 | +- **Simplified APIs** that reduce boilerplate code |
| 13 | +- **Testing utilities** for local development with MinIO and LocalStack |
| 14 | +- **Caching mechanisms** for improved performance |
| 15 | +- **Helper classes** for common AWS patterns |
14 | 16 |
|
15 | | -`pip3 install osbot-aws` |
| 17 | +## Supported AWS Services |
16 | 18 |
|
17 | | -https://pypi.org/project/osbot-aws/ |
| 19 | +- **IAM** - Identity and Access Management |
| 20 | +- **S3** - Simple Storage Service |
| 21 | +- **Lambda** - Serverless Functions |
| 22 | +- **EC2** - Elastic Compute Cloud |
| 23 | +- **ECS** - Elastic Container Service |
| 24 | +- **DynamoDB** - NoSQL Database |
| 25 | +- **API Gateway** - REST and WebSocket APIs |
| 26 | +- **Bedrock** - AI/ML Models |
| 27 | +- **Route 53** - DNS Service |
| 28 | +- **STS** - Security Token Service |
| 29 | +- **CloudWatch Logs** - Logging Service |
| 30 | +- **Organizations** - Account Management |
| 31 | +- **CodeArtifact** - Package Repository |
18 | 32 |
|
19 | | -### Previous release |
| 33 | +## Installation |
20 | 34 |
|
21 | | -Previous stable release is v1.0.0 and is available at https://github.com/owasp-sbot/OSBot-AWS/releases/tag/v1.0.0 |
| 35 | +```bash |
| 36 | +pip install osbot-aws |
| 37 | +``` |
| 38 | + |
| 39 | +## Quick Start |
| 40 | + |
| 41 | +### Basic AWS Session Setup |
| 42 | + |
| 43 | +```python |
| 44 | +from osbot_aws.apis.Session import Session |
| 45 | + |
| 46 | +# Create a session (uses default AWS credentials) |
| 47 | +session = Session() |
| 48 | + |
| 49 | +# Get a client for any AWS service |
| 50 | +s3_client = session.client('s3') |
| 51 | +lambda_client = session.client('lambda') |
| 52 | +``` |
| 53 | + |
| 54 | +### Working with S3 |
| 55 | + |
| 56 | +```python |
| 57 | +from osbot_aws.aws.s3.S3 import S3 |
| 58 | + |
| 59 | +s3 = S3() |
| 60 | + |
| 61 | +# Create a bucket |
| 62 | +s3.bucket_create('my-bucket', region='us-east-1') |
| 63 | + |
| 64 | +# Upload a file |
| 65 | +s3.file_upload_to_key('/path/to/file.txt', 'my-bucket', 'file.txt') |
| 66 | + |
| 67 | +# Download a file |
| 68 | +s3.file_download('my-bucket', 'file.txt') |
| 69 | + |
| 70 | +# List files |
| 71 | +files = s3.find_files('my-bucket', prefix='folder/') |
| 72 | + |
| 73 | +# Delete a file |
| 74 | +s3.file_delete('my-bucket', 'file.txt') |
| 75 | +``` |
| 76 | + |
| 77 | +### Working with Lambda |
| 78 | + |
| 79 | +```python |
| 80 | +from osbot_aws.aws.lambda_.Lambda import Lambda |
| 81 | + |
| 82 | +# Create a Lambda handler |
| 83 | +lambda_func = Lambda('my-function') |
| 84 | + |
| 85 | +# Configure the function |
| 86 | +lambda_func.set_role('arn:aws:iam::123456789:role/lambda-role') |
| 87 | +lambda_func.set_s3_bucket('my-deployment-bucket') |
| 88 | +lambda_func.set_s3_key('deployments/my-function.zip') |
| 89 | + |
| 90 | +# Create or update the function |
| 91 | +lambda_func.update() |
| 92 | + |
| 93 | +# Invoke the function |
| 94 | +result = lambda_func.invoke({'key': 'value'}) |
| 95 | + |
| 96 | +# Get function logs |
| 97 | +logs = lambda_func.log_group().messages() |
| 98 | +``` |
| 99 | + |
| 100 | +### Working with DynamoDB |
| 101 | + |
| 102 | +```python |
| 103 | +from osbot_aws.aws.dynamo_db.Dynamo_DB import Dynamo_DB |
| 104 | +from osbot_aws.aws.dynamo_db.Dynamo_DB__Table import Dynamo_DB__Table |
| 105 | + |
| 106 | +# Create a table handler |
| 107 | +table = Dynamo_DB__Table(table_name='my-table', key_name='id') |
| 108 | + |
| 109 | +# Create the table |
| 110 | +table.create_table() |
| 111 | + |
| 112 | +# Add a document |
| 113 | +document = {'id': '123', 'name': 'John', 'age': 30} |
| 114 | +table.add_document(document) |
| 115 | + |
| 116 | +# Get a document |
| 117 | +doc = table.document('123') |
| 118 | + |
| 119 | +# Query all documents |
| 120 | +all_docs = table.documents_all() |
| 121 | + |
| 122 | +# Delete the table |
| 123 | +table.delete_table() |
| 124 | +``` |
| 125 | + |
| 126 | +### Working with IAM |
| 127 | + |
| 128 | +```python |
| 129 | +from osbot_aws.aws.iam.IAM import IAM |
| 130 | +from osbot_aws.aws.iam.IAM_Role import IAM_Role |
| 131 | + |
| 132 | +# Create a role |
| 133 | +role = IAM_Role('my-lambda-role') |
| 134 | + |
| 135 | +# Define assume role policy for Lambda |
| 136 | +assume_policy = { |
| 137 | + "Version": "2012-10-17", |
| 138 | + "Statement": [{ |
| 139 | + "Effect": "Allow", |
| 140 | + "Principal": {"Service": "lambda.amazonaws.com"}, |
| 141 | + "Action": "sts:AssumeRole" |
| 142 | + }] |
| 143 | +} |
| 144 | + |
| 145 | +# Create the role |
| 146 | +role.create(assume_policy) |
| 147 | + |
| 148 | +# Attach a policy |
| 149 | +role.attach_policy('my-policy', policy_document={ |
| 150 | + "Version": "2012-10-17", |
| 151 | + "Statement": [{ |
| 152 | + "Effect": "Allow", |
| 153 | + "Action": "s3:*", |
| 154 | + "Resource": "*" |
| 155 | + }] |
| 156 | +}) |
| 157 | +``` |
| 158 | + |
| 159 | +### Using Temporary Roles |
| 160 | + |
| 161 | +```python |
| 162 | +from osbot_aws.aws.iam.IAM_Assume_Role import IAM_Assume_Role |
| 163 | + |
| 164 | +# Create a temporary role with specific permissions |
| 165 | +role = IAM_Assume_Role( |
| 166 | + role_name='temp-role', |
| 167 | + policies_to_add=[ |
| 168 | + {'service': 's3', 'action': '*', 'resource': '*'} |
| 169 | + ] |
| 170 | +) |
| 171 | + |
| 172 | +# Create the role and get credentials |
| 173 | +role.create_role() |
| 174 | + |
| 175 | +# Use the role to create a boto3 client |
| 176 | +s3_client = role.boto3_client('s3') |
| 177 | +``` |
| 178 | + |
| 179 | +## Configuration |
| 180 | + |
| 181 | +### Environment Variables |
| 182 | + |
| 183 | +OSBot-AWS uses several environment variables for configuration: |
| 184 | + |
| 185 | +```bash |
| 186 | +# AWS Credentials (if not using default profile) |
| 187 | +AWS_ACCESS_KEY_ID=your-access-key |
| 188 | +AWS_SECRET_ACCESS_KEY=your-secret-key |
| 189 | +AWS_DEFAULT_REGION=us-east-1 |
| 190 | + |
| 191 | +# Optional: Skip AWS credential checks (for development) |
| 192 | +DEV_SKIP_AWS_KEY_CHECK=True |
| 193 | + |
| 194 | +# Optional: S3 bucket for Lambda deployments |
| 195 | +OSBOT_AWS_LAMBDA_S3_BUCKET=my-lambda-bucket |
| 196 | +``` |
| 197 | + |
| 198 | +### Using .env Files |
| 199 | + |
| 200 | +Create a `.env` file in your project root: |
| 201 | + |
| 202 | +```bash |
| 203 | +AWS_PROFILE=my-profile |
| 204 | +AWS_DEFAULT_REGION=us-east-1 |
| 205 | +``` |
| 206 | + |
| 207 | +Load it in your code: |
| 208 | + |
| 209 | +```python |
| 210 | +from osbot_utils.utils.Env import load_dotenv |
| 211 | + |
| 212 | +load_dotenv() |
| 213 | +``` |
| 214 | + |
| 215 | +## Advanced Features |
| 216 | + |
| 217 | +### Lambda Dependencies Management |
| 218 | + |
| 219 | +```python |
| 220 | +from osbot_aws.aws.lambda_.dependencies.Lambda__Dependency import Lambda__Dependency |
| 221 | + |
| 222 | +# Install a package and upload to S3 for Lambda use |
| 223 | +dependency = Lambda__Dependency('requests') |
| 224 | +dependency.install_and_upload() |
| 225 | + |
| 226 | +# Load dependency inside Lambda function |
| 227 | +from osbot_aws.aws.lambda_.boto3__lambda import load_dependency |
| 228 | + |
| 229 | +def lambda_handler(event, context): |
| 230 | + load_dependency('requests') |
| 231 | + import requests |
| 232 | + # Use requests... |
| 233 | +``` |
| 234 | + |
| 235 | +### S3 Virtual Storage |
| 236 | + |
| 237 | +```python |
| 238 | +from osbot_aws.aws.s3.S3__Virtual_Storage import Virtual_Storage__S3 |
| 239 | +from osbot_aws.aws.s3.S3__DB_Base import S3__DB_Base |
| 240 | + |
| 241 | +# Create virtual storage backed by S3 |
| 242 | +s3_db = S3__DB_Base() |
| 243 | +s3_db.setup() |
| 244 | + |
| 245 | +storage = Virtual_Storage__S3(s3_db=s3_db) |
| 246 | + |
| 247 | +# Use like local storage |
| 248 | +storage.json__save('data/config.json', {'setting': 'value'}) |
| 249 | +data = storage.json__load('data/config.json') |
| 250 | +``` |
| 251 | + |
| 252 | +### Bedrock AI Integration |
| 253 | + |
| 254 | +```python |
| 255 | +from osbot_aws.aws.bedrock.Bedrock import Bedrock |
| 256 | + |
| 257 | +bedrock = Bedrock(region_name='us-east-1') |
| 258 | + |
| 259 | +# List available models |
| 260 | +models = bedrock.models() |
| 261 | + |
| 262 | +# Invoke a model |
| 263 | +response = bedrock.model_invoke( |
| 264 | + model_id='anthropic.claude-v2', |
| 265 | + body={ |
| 266 | + 'prompt': 'Hello, how are you?', |
| 267 | + 'max_tokens_to_sample': 100 |
| 268 | + } |
| 269 | +) |
| 270 | +``` |
| 271 | + |
| 272 | +## Testing |
| 273 | + |
| 274 | +### Using LocalStack |
| 275 | + |
| 276 | +```python |
| 277 | +from osbot_aws.aws.s3.S3 import S3 |
| 278 | +from osbot_aws.aws.session.Session__Kwargs__S3 import Session__Kwargs__S3 |
| 279 | + |
| 280 | +# Configure S3 to use LocalStack |
| 281 | +session_kwargs = Session__Kwargs__S3( |
| 282 | + endpoint_url='http://localhost:4566' |
| 283 | +) |
| 284 | + |
| 285 | +s3 = S3(session_kwargs__s3=session_kwargs) |
| 286 | +``` |
| 287 | + |
| 288 | +### Using MinIO |
| 289 | + |
| 290 | +```python |
| 291 | +from osbot_aws.aws.s3.S3__Minio import S3__Minio |
| 292 | + |
| 293 | +# Connect to MinIO (compatible with S3 API) |
| 294 | +minio = S3__Minio() |
| 295 | +s3 = minio.s3() |
| 296 | + |
| 297 | +# Use like regular S3 |
| 298 | +s3.bucket_create('test-bucket', region='us-east-1') |
| 299 | +``` |
| 300 | + |
| 301 | +## Error Handling |
| 302 | + |
| 303 | +```python |
| 304 | +from osbot_aws.aws.sts.STS import check_current_aws_credentials |
| 305 | + |
| 306 | +# Check AWS credentials before proceeding |
| 307 | +result = check_current_aws_credentials(raise_exception=False) |
| 308 | + |
| 309 | +if result.get('status') == 'error': |
| 310 | + print(f"AWS credentials error: {result.get('message')}") |
| 311 | +else: |
| 312 | + print("AWS credentials are valid") |
| 313 | +``` |
| 314 | + |
| 315 | +## Best Practices |
| 316 | + |
| 317 | +1. **Always use context managers** when available: |
| 318 | +```python |
| 319 | +with IAM_Role('my-role') as role: |
| 320 | + role.create(assume_policy) |
| 321 | +``` |
| 322 | + |
| 323 | +2. **Use type-safe classes** for better IDE support and error checking |
| 324 | + |
| 325 | +3. **Cache expensive operations** using the built-in caching decorators |
| 326 | + |
| 327 | +4. **Use temporary roles** for least-privilege access: |
| 328 | +```python |
| 329 | +from osbot_aws.aws.s3.S3__with_temp_role import S3__with_temp_role |
| 330 | + |
| 331 | +s3 = S3__with_temp_role() |
| 332 | +# Automatically creates and uses a temporary role |
| 333 | +``` |
| 334 | + |
| 335 | +5. **Handle AWS rate limits** with built-in waiters: |
| 336 | +```python |
| 337 | +lambda_func.wait_for_function_update_to_complete() |
| 338 | +``` |
| 339 | + |
| 340 | +## Contributing |
| 341 | + |
| 342 | +Contributions are welcome! Please feel free to submit a Pull Request. |
| 343 | + |
| 344 | +## License |
| 345 | + |
| 346 | +See LICENSE file for details. |
| 347 | + |
| 348 | +## Related Projects |
| 349 | + |
| 350 | +- **OSBot-Utils** - Utility functions and helpers |
| 351 | +- **OSBot-Local-Stack** - LocalStack integration utilities |
| 352 | + |
| 353 | +## Support |
| 354 | + |
| 355 | +For issues, questions, or contributions, please visit the GitHub repository. |
0 commit comments