Metadata-Version: 2.4
Name: aws-cost-analysis
Version: 0.6.0
Summary: CLI and library for analyzing AWS costs across accounts and services
Project-URL: Homepage, https://github.com/lincolnloop/aws-cost-analysis
Project-URL: Repository, https://github.com/lincolnloop/aws-cost-analysis
Project-URL: Issues, https://github.com/lincolnloop/aws-cost-analysis/issues
Author-email: Brendan Smith <brendan@lincolnloop.com>
License-Expression: MIT
License-File: LICENSE
Keywords: aws,billing,cost-explorer,finops
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: System :: Systems Administration
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: boto3>=1.34
Requires-Dist: click>=8.1
Requires-Dist: python-dateutil>=2.9
Requires-Dist: tabulate>=0.9
Provides-Extra: viz
Requires-Dist: plotly>=5.20; extra == 'viz'
Description-Content-Type: text/markdown

# aws-cost-analysis

CLI and library for analyzing AWS costs across accounts and services. Wraps the
AWS Cost Explorer API and adds month-over-month pivots, change alerts, and
usage-type breakdowns, with optional chart export. A Lincoln Loop project.

The core install is intentionally lightweight — only `boto3`, `click`,
`tabulate`, and `python-dateutil`.

## Install

From a tagged release on GitHub:

```bash
pip install "git+https://github.com/lincolnloop/aws-cost-analysis@v0.6.0"
# with chart export:
pip install "aws-cost-analysis[viz] @ git+https://github.com/lincolnloop/aws-cost-analysis@v0.6.0"
```

Or run the CLI without installing it:

```bash
uvx --from "git+https://github.com/lincolnloop/aws-cost-analysis@v0.6.0" \
  aws-costs analyze-services --months 3 --table
```

For local development:

```bash
pyenv install 3.12  # if not already installed
uv sync             # builds .venv and installs the project editable
```

## AWS credentials

By default the tools use the standard boto3 credential chain. Pick a profile via
`AWS_PROFILE`, or pass `--profile` / `--region` to the CLI:

```bash
export AWS_PROFILE=my-profile
aws-costs --profile my-profile --region us-east-1 analyze-services --table
```

Library callers can inject any `boto3.Session` (see [Library usage](#library-usage)),
which is the supported way to drive a specific profile or assumed-role
credentials without mutating process-wide state.

Required IAM permissions:

- `ce:GetCostAndUsage`
- `organizations:ListAccounts` (for account-name resolution)

## CLI

```bash
aws-costs analyze-accounts --months 3 --table
aws-costs analyze-services --months 6 --format csv
aws-costs analyze-usage "Amazon RDS" --months 2 --table
aws-costs analyze-usage-types ec2 --months 3 --table
aws-costs analyze-alerts --amount 50 --percent 15
aws-costs list-available-services
```

Common options:

| flag | description |
|---|---|
| `--months N` | Months of history (default `2`) |
| `--include-current` | Include the current (incomplete) month |
| `--format json\|csv\|tsv\|html` | Persisted output format |
| `--table` | Print pivot table to terminal |
| `--sheets` | Print CSV to stdout (accounts only) |
| `--output-dir DIR` | Output directory (default `cost_reports/`) |

Outputs land in `cost_reports/{AWS_PROFILE}/` with timestamped filenames like
`account_costs_2m_20260504_171500_pivot.json`.

## Library usage

The analysis functions are importable and return plain Python `list[dict]`
records — a tidy "raw" list and a formatted month-over-month pivot:

```python
from aws_cost_analysis.cost_analysis import analyze_service_costs

raw, pivot = analyze_service_costs(months=6)
# raw  → [{"month": "2026-04", "key": "AWS Lambda", "cost": 9.99}, ...]
# pivot → [{"Service": "AWS Lambda", "2026-04": "$9.99", ..., "+/- $": "...", "+/- %": "..."}, ...]
print(pivot)
```

Every function that talks to AWS accepts an optional `session` keyword. When
omitted, the standard boto3 credential chain is used. Pass an explicit
`boto3.Session` to target a specific profile or assumed-role credentials —
useful for multi-account tooling and tests, with no process-wide state:

```python
import boto3
from aws_cost_analysis.cost_analysis import analyze_account_costs

# A specific named profile
session = boto3.Session(profile_name="payer", region_name="us-east-1")
raw, pivot = analyze_account_costs(months=3, session=session)

# Or assumed-role credentials for a client's payer account
sts = boto3.client("sts")
creds = sts.assume_role(
    RoleArn="arn:aws:iam::123456789012:role/CostExplorerReadOnly",
    RoleSessionName="cost-analysis",
)["Credentials"]
session = boto3.Session(
    aws_access_key_id=creds["AccessKeyId"],
    aws_secret_access_key=creds["SecretAccessKey"],
    aws_session_token=creds["SessionToken"],
)
raw, pivot = analyze_account_costs(months=3, session=session)
```

`list_services(...)` accepts the same `session` keyword.

## Development

```bash
uv sync
.venv/bin/pytest
.venv/bin/ruff check aws_cost_analysis tests
uv run mypy aws_cost_analysis
```

## Architecture

```
aws_cost_analysis/
├── billing.py          # Time-period helpers
├── cost_analysis.py    # Cost Explorer queries + data shaping; returns list[dict] records
├── cost_alerts.py      # Threshold-based change detection
└── cli.py              # Click CLI (entry: aws-costs)
```

Cost Explorer results flow through `create_cost_dataframe` → `create_cost_pivot`,
which produces a tidy `list[dict]` of raw records plus a formatted pivot with
`+/- $` and `+/- %` delta columns and a `Total` row appended last.

## License

MIT — see [LICENSE](LICENSE). Copyright © Lincoln Loop.
