aws-simple
A clean, simple Python wrapper around AWS services (S3, Textract, Bedrock).
Features
- Simple API: Clean, intuitive interface without exposing Boto3 complexity
- Environment-based configuration: No credentials or config in code
- Structured Textract output: Transforms AWS Blocks into clean, serializable JSON
- Type-safe: Fully typed with Python 3.10+ support
- Production-ready: Works with IAM roles, Docker, CI/CD pipelines
Installation
pip install aws-simple
Or install from source:
pip install -e .
Configuration
All configuration is done via environment variables:
# Required
export AWS_REGION=us-east-1
export AWS_S3_BUCKET=my-bucket-name
# Optional
export AWS_PROFILE=my-profile # For local development
export AWS_BEDROCK_MODEL_ID=anthropic.claude-3-5-sonnet-20241022-v2:0
export AWS_TEXTRACT_REGION=us-east-1
export AWS_BEDROCK_REGION=us-east-1
export AWS_SSL_VERIFY=true # SSL certificate verification (default: true, set to false to disable)
Or use a .env file (see .env.example).
AWS Credentials
AWS credentials should be configured separately via:
- IAM Role (recommended for production/EC2/ECS/Lambda)
- ~/.aws/credentials file (for local development)
- Environment variables
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY(not recommended)
Usage
S3 Operations
from aws_simple import s3
# Upload file
s3.upload_file("document.pdf", "docs/document.pdf")
# Download file
s3.download_file("docs/document.pdf", "/tmp/document.pdf")
# Read object as bytes
content = s3.read_object("docs/document.pdf")
# List objects
files = s3.list_objects(prefix="docs/")
# Check if object exists
exists = s3.object_exists("docs/document.pdf")
Textract - Document Extraction
⚠️ Current limitation: 1 page per request
extract_text_from_file,extract_text_from_s3,extract_text_simple_from_file, andextract_text_simple_from_s3use the synchronous Textract APIs (analyze_document/detect_document_textwithDocument={"Bytes": ...}orDocument={"S3Object": ...}). These APIs reliably process only an image or a single-page PDF. For multi-page PDFs, only the first page is reliable (AWS does not guarantee behavior for subsequent pages).Supporting multi-page PDFs requires switching to the asynchronous Textract APIs (
StartDocumentAnalysis/StartDocumentTextDetectionvia S3) or splitting the document client-side before extraction — see #11.
from aws_simple import textract
import json
# Extract from local file (with tables)
doc = textract.extract_text_from_file("invoice.pdf")
# Extract from S3 (with tables)
doc = textract.extract_text_from_s3("docs/invoice.pdf")
# Access structured data
print(doc.full_text) # All text concatenated
print(f"Pages: {len(doc.pages)}")
# Access page details
page = doc.pages[0]
print(f"Lines: {len(page.lines)}")
print(f"Tables: {len(page.tables)}")
# Access lines
for line in page.lines:
print(f"{line.text} (confidence: {line.confidence})")
# Access tables
for table in page.tables:
print(f"Table: {table.rows}x{table.columns}")
print(table.cells) # 2D matrix of cell values
# Serialize to JSON
doc_json = doc.to_dict()
with open("result.json", "w") as f:
json.dump(doc_json, f, indent=2)
# Simple text extraction (faster, no tables)
text = textract.extract_text_simple_from_file("document.pdf")
Textract Output Format
The library transforms AWS Textract Blocks into a clean JSON structure:
{
"pages": [
{
"page_number": 1,
"width": 1.0,
"height": 1.0,
"lines": [
{
"text": "Invoice #12345",
"confidence": 99.5,
"bounding_box": {"top": 0.1, "left": 0.1, "width": 0.2, "height": 0.05}
}
],
"tables": [
{
"rows": 3,
"columns": 2,
"cells": [
["Item", "Price"],
["Product A", "$10"],
["Product B", "$20"]
],
"confidence": 98.7
}
],
"raw_text": "Invoice #12345\n..."
}
],
"full_text": "All text from all pages concatenated...",
"metadata": {
"document_metadata": {...},
"total_pages": 1
}
}
Bedrock - LLM Operations
Note: Supports Anthropic Claude, Amazon Titan, Meta Llama and Mistral models, selected automatically from the
model_id(e.g.anthropic.claude-3-5-sonnet-20241022-v2:0,amazon.titan-text-express-v1,meta.llama3-8b-instruct-v1:0,mistral.mistral-7b-instruct-v0:2). Callinginvoke()/invoke_json()with a model ID from another family raisesBedrockError.
from aws_simple import bedrock
# Simple text generation
response = bedrock.invoke("Explain AWS Lambda in one sentence")
print(response)
# With system prompt and parameters
response = bedrock.invoke(
prompt="What are the benefits of serverless?",
system_prompt="You are an AWS solutions architect.",
temperature=0.7,
max_tokens=500
)
# Request JSON output
prompt = """
List 3 AWS services with their use cases.
Format: {"services": [{"name": "...", "use_case": "..."}]}
"""
data = bedrock.invoke_json(prompt)
print(data["services"])
# Use different model
response = bedrock.invoke(
"Summarize this text...",
model_id="anthropic.claude-3-5-sonnet-20241022-v2:0"
)
Combined Workflow
from aws_simple import s3, textract, bedrock
import json
# 1. Upload document
s3.upload_file("invoice.pdf", "invoices/2024/inv_001.pdf")
# 2. Extract content
doc = textract.extract_text_from_s3("invoices/2024/inv_001.pdf")
# 3. Analyze with LLM
prompt = f"""
Extract key information from this invoice:
{doc.full_text}
Return JSON with: invoice_number, date, total, vendor
"""
invoice_data = bedrock.invoke_json(prompt)
print(json.dumps(invoice_data, indent=2))
Architecture
aws-simple/
├── config.py # Environment variable configuration
├── exceptions.py # Custom exceptions
├── _clients.py # AWS client factory (internal)
├── s3.py # S3 operations
├── textract.py # Textract operations
├── bedrock.py # Bedrock operations
├── models/ # Data models
│ └── textract.py # TextractDocument, TextractPage, etc.
└── _parsers/ # Internal parsers
└── textract_parser.py # Transforms Blocks → JSON
Design Principles
- No Boto3 in public API: AWS implementation details are hidden
- Environment-based config: All configuration via env vars
- Clean output formats: No raw AWS responses exposed
- Type safety: Full type hints for better IDE support
- Simple error handling: Custom exceptions for each service
- Production-ready: Compatible with Docker, IAM roles, CI/CD
Exceptions
from aws_simple import (
AWSSimpleError, # Base exception
ConfigurationError, # Missing/invalid configuration
S3Error, # S3 operation failures
TextractError, # Textract operation failures
BedrockError, # Bedrock operation failures
ClientInitializationError # AWS client init failures
)
try:
doc = textract.extract_text_from_s3("missing.pdf")
except TextractError as e:
print(f"Extraction failed: {e}")
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Type checking
mypy src/
# Linting
ruff check src/
Requirements
- Python ≥ 3.10
- boto3 ≥ 1.34.0
- python-dotenv ≥ 1.0.0
License
Apache-2.0 — see the LICENSE file for details.
Support
For issues and feature requests, please visit the GitHub repository.
Metadata
Release files for aws-simple 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| aws_simple-1.0.0.tar.gz | 40.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aws_simple-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 60.7 kB
Release files / aws_simple-1.0.0.tar.gz
| Download URL | aws_simple-1.0.0.tar.gz |
|---|---|
| Size | 40.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
964591ff808f309e8364965cb99cd040c0409458f13648af22d743d85d5e6522
|
|
BLAKE2b-256 checksum How to use checksums |
222ff2a48f7382ce651e698bf546eb1ac3d07be57c04db14ef87839247029d32
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / aws_simple-1.0.0-py3-none-any.whl
| Download URL | aws_simple-1.0.0-py3-none-any.whl |
|---|---|
| Size | 20.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
692fc3a77dd4496a1fffa4b3f29be9070cb6edb45376bdff5f21d776b57d2fbd
|
|
BLAKE2b-256 checksum How to use checksums |
ce2d0b4c52658580fb0b71dfea76331a5964f0ee265aa75f111c3f7b2c344fd4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for aws-simple 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.