aws-cost-calculator-cli 1.0.2__py3-none-any.whl → 1.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of aws-cost-calculator-cli might be problematic. Click here for more details.

@@ -0,0 +1,437 @@
1
+ Metadata-Version: 2.4
2
+ Name: aws-cost-calculator-cli
3
+ Version: 1.8.2
4
+ Summary: AWS Cost Calculator CLI - Calculate daily and annual AWS costs across multiple accounts
5
+ Home-page: https://github.com/trilogy-group/aws-cost-calculator
6
+ Author: Cost Optimization Team
7
+ Author-email:
8
+ Project-URL: Documentation, https://github.com/trilogy-group/aws-cost-calculator/blob/main/README.md
9
+ Keywords: aws cost calculator billing optimization cloud
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: System Administrators
13
+ Classifier: Topic :: System :: Monitoring
14
+ Classifier: Topic :: Utilities
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: click>=8.0.0
25
+ Requires-Dist: boto3>=1.26.0
26
+ Requires-Dist: requests>=2.28.0
27
+ Dynamic: author
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: keywords
33
+ Dynamic: license-file
34
+ Dynamic: project-url
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # AWS Cost Calculator (cc)
40
+
41
+ A CLI tool to quickly calculate AWS costs across multiple accounts.
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install aws-cost-calculator-cli
47
+ ```
48
+
49
+ Or upgrade to the latest version:
50
+ ```bash
51
+ pip install --upgrade aws-cost-calculator-cli
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ### Authentication Methods
57
+
58
+ The CLI supports three authentication methods:
59
+
60
+ #### 1. SSO (Recommended)
61
+ ```bash
62
+ # The CLI will automatically trigger SSO login if needed
63
+ cc calculate --profile myprofile --sso my_sso_profile
64
+ ```
65
+
66
+ #### 2. Static Credentials
67
+ ```bash
68
+ cc calculate --profile myprofile \
69
+ --access-key-id ASIA... \
70
+ --secret-access-key ... \
71
+ --session-token ...
72
+ ```
73
+
74
+ #### 3. Environment Variables
75
+ ```bash
76
+ # For SSO
77
+ export AWS_PROFILE=my_sso_profile
78
+ cc calculate --profile myprofile
79
+
80
+ # For static credentials
81
+ export AWS_ACCESS_KEY_ID=ASIA...
82
+ export AWS_SECRET_ACCESS_KEY=...
83
+ export AWS_SESSION_TOKEN=...
84
+ cc calculate --profile myprofile
85
+ ```
86
+
87
+ ### Basic Usage
88
+
89
+ ```bash
90
+ # Default: Today minus 2 days, going back 30 days
91
+ cc calculate --profile myprofile --sso my_sso_profile
92
+
93
+ # Specific start date
94
+ cc calculate --profile myprofile --sso my_sso_profile --start-date 2025-11-04
95
+
96
+ # Custom offset and window
97
+ cc calculate --profile myprofile --sso my_sso_profile --offset 2 --window 30
98
+
99
+ # JSON output
100
+ cc calculate --profile myprofile --sso my_sso_profile --json-output
101
+ ```
102
+
103
+ ### 4. Analyze cost trends
104
+
105
+ All commands support the same authentication options:
106
+
107
+ ```bash
108
+ # With SSO
109
+ cc trends --profile myprofile --sso my_sso_profile
110
+
111
+ # With static credentials
112
+ cc trends --profile myprofile --access-key-id ASIA... --secret-access-key ... --session-token ...
113
+
114
+ # With environment variables
115
+ export AWS_PROFILE=my_sso_profile
116
+ cc trends --profile myprofile
117
+
118
+ # Analyze more weeks
119
+ cc trends --profile myprofile --sso my_sso_profile --weeks 5
120
+
121
+ # Custom output file
122
+ cc trends --profile myprofile --sso my_sso_profile --output weekly_trends.md
123
+
124
+ # JSON output
125
+ cc trends --profile myprofile --sso my_sso_profile --json-output
126
+ ```
127
+
128
+ ### 5. Monthly and drill-down analysis
129
+
130
+ ```bash
131
+ # Monthly trends
132
+ cc monthly --profile myprofile --sso my_sso_profile
133
+
134
+ # Drill down by service
135
+ cc drill --profile myprofile --sso my_sso_profile --service "EC2 - Other"
136
+
137
+ # Drill down by account
138
+ cc drill --profile myprofile --sso my_sso_profile --account 123456789012
139
+ ```
140
+
141
+ ### 6. List profiles
142
+
143
+ ```bash
144
+ cc list-profiles
145
+ ```
146
+
147
+ ## Authentication
148
+
149
+ ### Overview
150
+
151
+ The CLI supports three authentication methods, all of which work with every command (`calculate`, `trends`, `monthly`, `drill`):
152
+
153
+ ### Method 1: SSO (Recommended)
154
+
155
+ The CLI automatically handles SSO login if your session has expired:
156
+
157
+ ```bash
158
+ cc calculate --profile myprofile --sso my_sso_profile
159
+ ```
160
+
161
+ **How it works:**
162
+ 1. CLI checks if SSO session is valid using `aws sts get-caller-identity`
163
+ 2. If expired, automatically runs `aws sso login --profile my_sso_profile`
164
+ 3. Opens browser for authentication
165
+ 4. Proceeds with cost calculation once authenticated
166
+
167
+ **Benefits:**
168
+ - No manual SSO login required
169
+ - Automatic session refresh
170
+ - Most secure method
171
+ - Works with AWS IAM Identity Center
172
+
173
+ ### Method 2: Static Credentials
174
+
175
+ Pass temporary credentials directly via CLI flags:
176
+
177
+ ```bash
178
+ cc calculate --profile myprofile \
179
+ --access-key-id ASIA... \
180
+ --secret-access-key ... \
181
+ --session-token ...
182
+ ```
183
+
184
+ **Use cases:**
185
+ - CI/CD pipelines
186
+ - Temporary credentials from STS
187
+ - Automated scripts
188
+ - When SSO is not available
189
+
190
+ ### Method 3: Environment Variables
191
+
192
+ Set credentials in your shell environment:
193
+
194
+ ```bash
195
+ # For SSO
196
+ export AWS_PROFILE=my_sso_profile
197
+ cc calculate --profile myprofile
198
+
199
+ # For static credentials
200
+ export AWS_ACCESS_KEY_ID=ASIA...
201
+ export AWS_SECRET_ACCESS_KEY=...
202
+ export AWS_SESSION_TOKEN=...
203
+ cc calculate --profile myprofile
204
+ ```
205
+
206
+ **Benefits:**
207
+ - No need to pass credentials with each command
208
+ - Works with existing AWS CLI configuration
209
+ - Can be set in shell profile (~/.zshrc, ~/.bashrc)
210
+
211
+ ### Profile Configuration
212
+
213
+ Profiles can be stored locally or fetched from a backend API:
214
+
215
+ **Local storage:** `~/.config/cost-calculator/profiles.json`
216
+ ```json
217
+ {
218
+ "myprofile": {
219
+ "accounts": ["123456789012", "234567890123", ...]
220
+ }
221
+ }
222
+ ```
223
+
224
+ **Backend API:** Set `COST_API_SECRET` environment variable
225
+
226
+ Quick setup (saves to shell profile):
227
+ ```bash
228
+ cc setup-api
229
+ # Enter your API secret when prompted (input will be hidden)
230
+ ```
231
+
232
+ **CUR Configuration (for --resources flag):**
233
+
234
+ To use resource-level queries, configure CUR settings:
235
+ ```bash
236
+ cc setup-cur
237
+ # Enter: Database name, table name, S3 output location
238
+ ```
239
+
240
+ This saves configuration to `~/.config/cost-calculator/cur_config.json`
241
+
242
+ Or set manually:
243
+ ```bash
244
+ export COST_API_SECRET="your-api-secret"
245
+ cc calculate --profile myprofile --sso my_sso_profile
246
+ ```
247
+
248
+ The CLI will automatically fetch profile configuration from the backend if `COST_API_SECRET` is set.
249
+
250
+ ## How It Works
251
+
252
+ ### Date Calculation
253
+ - **Start Date**: Defaults to today, or specify with `--start-date`
254
+ - **Offset**: Days to go back from start date (default: 2)
255
+ - **Window**: Number of days to analyze (default: 30)
256
+
257
+ Example: If today is Nov 4, 2025:
258
+ - With offset=2, window=30: Analyzes Oct 3 - Nov 2 (30 days)
259
+
260
+ ### Cost Calculation
261
+ 1. **Operational Costs**: Sum of daily costs ÷ window days
262
+ 2. **Support Allocation**:
263
+ - Gets support cost from the analysis month
264
+ - Divides by 2 (50% allocation)
265
+ - Divides by days in that month
266
+ 3. **Daily Rate**: Operational + Support per day
267
+ 4. **Annual Projection**: Daily rate × 365
268
+
269
+ ### Filters Applied
270
+ - **Billing Entity**: AWS only (excludes marketplace)
271
+ - **Excluded**: Tax, Support (calculated separately)
272
+ - **Metric**: Net Amortized Cost
273
+
274
+ ## Configuration
275
+
276
+ Profiles are stored in: `~/.config/cost-calculator/profiles.json`
277
+
278
+ Example:
279
+ ```json
280
+ {
281
+ "myprofile": {
282
+ "aws_profile": "my_aws_profile",
283
+ "accounts": ["123456789012", "234567890123", "345678901234"]
284
+ }
285
+ }
286
+ ```
287
+
288
+ ## Examples
289
+
290
+ ```bash
291
+ # Quick daily check
292
+ cc calculate --profile myprofile
293
+
294
+ # Historical analysis
295
+ cc calculate --profile myprofile --start-date 2025-10-01
296
+
297
+ # Export to JSON for processing
298
+ cc calculate --profile myprofile --json-output > costs.json
299
+
300
+ # Different window size
301
+ cc calculate --profile myprofile --window 60
302
+
303
+ # Weekly cost trends analysis
304
+ cc trends --profile myprofile
305
+
306
+ # Analyze last 8 weeks
307
+ cc trends --profile myprofile --weeks 8
308
+
309
+ # Monthly cost trends analysis
310
+ cc monthly --profile myprofile
311
+
312
+ # Analyze last 12 months
313
+ cc monthly --profile myprofile --months 12
314
+
315
+ # Drill down into specific service
316
+ cc drill --profile myprofile --service "EC2 - Other"
317
+
318
+ # Drill down into specific account
319
+ cc drill --profile myprofile --account 123456789012
320
+
321
+ # Drill down into service within account
322
+ cc drill --profile myprofile --service "EC2 - Other" --account 123456789012
323
+ ```
324
+
325
+ ## Trends Report
326
+
327
+ The `trends` command generates a markdown report with **two types of analysis**:
328
+
329
+ ### 1. Week-over-Week (WoW)
330
+ Compares each week to the previous week - good for catching immediate spikes and changes.
331
+
332
+ ### 2. Trailing 30-Day (T-30)
333
+ Compares each week to the same week 4 weeks ago - filters out noise and shows sustained trends.
334
+
335
+ **Features:**
336
+ - **Service-level aggregation**: Shows total cost per service (not individual usage types)
337
+ - **Top 10 Increases/Decreases**: For each comparison period
338
+ - **Total rows**: Sum of top 10 changes for quick assessment
339
+ - **Filters**: Only shows changes >$10 and >5%
340
+
341
+ Example output:
342
+ ```
343
+ Week of Oct 19 → Week of Oct 26 (WoW)
344
+ Increases: 4, Decreases: 10
345
+ Top: EC2 - Other (+$949.12)
346
+
347
+ Week of Oct 26 vs Week of Sep 28 (T-30)
348
+ Increases: 10, Decreases: 10
349
+ Top: EC2 - Other (+$886.39)
350
+ ```
351
+
352
+ The report is saved to `cost_trends.md` by default and includes:
353
+ - Service name
354
+ - Previous/baseline cost
355
+ - Current cost
356
+ - Change amount and percentage
357
+ - Total of top 10 changes
358
+
359
+ ## Monthly Report
360
+
361
+ The `monthly` command generates month-over-month cost comparisons:
362
+
363
+ **Features:**
364
+ - **Service-level aggregation**: Shows total cost per service
365
+ - **Calendar month comparisons**: October vs September, September vs August, etc.
366
+ - **Top 10 Increases/Decreases**: For each month comparison
367
+ - **Total rows**: Sum of top 10 changes
368
+ - **Filters**: Only shows changes >$50 and >5%
369
+
370
+ Example output:
371
+ ```
372
+ October 2025 → November 2025
373
+ Increases: 1, Decreases: 10
374
+ Top: Savings Plans for AWS Compute usage (+$231,161.46)
375
+ ```
376
+
377
+ The report is saved to `monthly_trends.md` by default.
378
+
379
+ ## Drill-Down Analysis
380
+
381
+ The `drill` command allows you to investigate cost changes at different levels of detail:
382
+
383
+ **Funnel Approach:**
384
+ 1. **Start broad:** `cc trends` → See EC2 costs up $1000
385
+ 2. **Drill by service:** `cc drill --service "EC2 - Other"` → See which accounts
386
+ 3. **Drill deeper:** `cc drill --service "EC2 - Other" --account 123` → See usage types
387
+ 4. **Resource-level:** `cc drill --service "EC2 - Other" --account 123 --resources` → See individual instance IDs
388
+
389
+ **Features:**
390
+ - **Week-over-week cost analysis**: Compare costs between consecutive weeks
391
+ - **Month-over-month cost analysis**: Compare costs between consecutive months
392
+ - **Drill-down analysis**: Analyze costs by service, account, or usage type
393
+ - **Resource-level analysis**: See individual resource IDs and costs using CUR data (NEW in v1.7.0)
394
+ - **Pandas aggregations**: Time series analysis with sum, avg, std across all weeks
395
+ - **Volatility detection**: Identify services with high cost variability and outliers
396
+ - **Trend detection**: Auto-detect increasing/decreasing cost patterns
397
+ - **Search & filter**: Find services by pattern or cost threshold
398
+ - **Profile management**: CRUD operations for account profiles in DynamoDB
399
+ - **Markdown reports**: Generate formatted reports
400
+ - **JSON output**: Machine-readable output for automation
401
+ - **Lambda API backend**: Serverless backend with pandas/numpy support
402
+
403
+ Example output:
404
+ ```
405
+ # Drill by service
406
+ cc drill --profile myprofile --service "EC2 - Other"
407
+
408
+ Showing top accounts:
409
+ Week of Oct 19 → Week of Oct 26
410
+ Increases: 3, Decreases: 2
411
+ Top: 123456789012 (+$450.23)
412
+ ```
413
+
414
+ The report is saved to `drill_down.md` by default.
415
+
416
+ ## Output
417
+
418
+ ```
419
+ Analyzing: 2025-10-03 to 2025-11-02 (30 days)
420
+ AWS Profile: my_aws_profile
421
+ Accounts: 3
422
+
423
+ Fetching cost data...
424
+ Fetching support costs...
425
+ ============================================================
426
+ Period: 2025-10-03 to 2025-11-02
427
+ Days analyzed: 30
428
+ ============================================================
429
+ Total operational cost: $450,000.00
430
+ Daily operational: $14,516.13
431
+ Support (month): $15,000.00
432
+ Support per day (÷2÷days): $241.94
433
+ ============================================================
434
+ DAILY RATE: $14,758.07
435
+ ANNUAL PROJECTION: $5,386,695
436
+ ============================================================
437
+ ```
@@ -0,0 +1,15 @@
1
+ aws_cost_calculator_cli-1.8.2.dist-info/licenses/LICENSE,sha256=cYtmQZHNGGTXOtg3T7LHDRneleaH0dHXHfxFV3WR50Y,1079
2
+ cost_calculator/__init__.py,sha256=PJeIqvWh5AYJVrJxPPkI4pJnAt37rIjasrNS0I87kaM,52
3
+ cost_calculator/api_client.py,sha256=4ZI2XcGIN3FBeQqb7xOxQ91kCoeM43-rExiOELXoKBQ,2485
4
+ cost_calculator/cli.py,sha256=jkyPlHAdVgpk5LrP1T9YvBK4-K6hM5fd538VqIHw-7A,52255
5
+ cost_calculator/cur.py,sha256=QaZ_nyDSw5_cti-h5Ho6eYLbqzY5TWoub24DpyzIiSs,9502
6
+ cost_calculator/drill.py,sha256=hGi-prLgZDvNMMICQc4fl3LenM7YaZ3To_Ei4LKwrdc,10543
7
+ cost_calculator/executor.py,sha256=aWLELeisDu6b-5U5LDPDPnK5uJKilYcoUPerxPUqtYg,10435
8
+ cost_calculator/forensics.py,sha256=Ny5IbMhJF6kawQDiLDExQGb5C-zRDbbmziS5JoinmdA,12694
9
+ cost_calculator/monthly.py,sha256=6k9F8S7djhX1wGV3-T1MZP7CvWbbfhSTEaddwCfVu5M,7932
10
+ cost_calculator/trends.py,sha256=k_s4ylBX50sqoiM_fwepi58HW01zz767FMJhQUPDznk,12246
11
+ aws_cost_calculator_cli-1.8.2.dist-info/METADATA,sha256=wCkJT5XL6m3ESmbK0mdfzSpkWiJn9PJQ6nuUBelILXU,11978
12
+ aws_cost_calculator_cli-1.8.2.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
13
+ aws_cost_calculator_cli-1.8.2.dist-info/entry_points.txt,sha256=_5Qy4EcHbYVYrdgOu1E48faMHb9fLUl5VJ3djDHuJBo,47
14
+ aws_cost_calculator_cli-1.8.2.dist-info/top_level.txt,sha256=PRwGPPlNqASfyhGHDjSfyl4SXeE7GF3OVTu1tY1Uqyc,16
15
+ aws_cost_calculator_cli-1.8.2.dist-info/RECORD,,
@@ -0,0 +1,85 @@
1
+ """
2
+ API client for calling Lambda backend.
3
+ Falls back to local execution if API is not configured.
4
+ """
5
+ import os
6
+ import json
7
+ import requests
8
+ from pathlib import Path
9
+
10
+
11
+ def get_api_config():
12
+ """
13
+ Get API configuration.
14
+
15
+ Returns:
16
+ dict: API configuration with api_secret, or None if not configured
17
+ """
18
+ api_secret = os.environ.get('COST_API_SECRET', '')
19
+
20
+ if api_secret:
21
+ return {'api_secret': api_secret}
22
+
23
+ return None
24
+
25
+
26
+ def call_lambda_api(endpoint, credentials, accounts, **kwargs):
27
+ """
28
+ Call Lambda API endpoint.
29
+
30
+ Args:
31
+ endpoint: API endpoint name ('trends', 'monthly', 'drill')
32
+ credentials: dict with AWS credentials
33
+ accounts: list of account IDs
34
+ **kwargs: additional parameters for the specific endpoint
35
+
36
+ Returns:
37
+ dict: API response data
38
+
39
+ Raises:
40
+ Exception: if API call fails
41
+ """
42
+ api_config = get_api_config()
43
+
44
+ if not api_config:
45
+ raise Exception("API not configured. Set COST_API_SECRET environment variable.")
46
+
47
+ # Map endpoint names to Lambda URLs
48
+ endpoint_urls = {
49
+ 'trends': 'https://pq3mqntc6vuwi4zw5flulsoleq0yiqtl.lambda-url.us-east-1.on.aws/',
50
+ 'monthly': 'https://6aueebodw6q4zdeu3aaexb6tle0fqhhr.lambda-url.us-east-1.on.aws/',
51
+ 'drill': 'https://3ncm2gzxrsyptrhud3ua3x5lju0akvsr.lambda-url.us-east-1.on.aws/',
52
+ 'analyze': 'https://y6npmidtxwzg62nrqzkbacfs5q0edwgs.lambda-url.us-east-1.on.aws/',
53
+ 'profiles': 'https://64g7jq7sjygec2zmll5lsghrpi0txrzo.lambda-url.us-east-1.on.aws/',
54
+ 'forensics': 'https://gaekfzz7sc2hwn4mjyk64sieke0vadfo.lambda-url.us-east-1.on.aws/' # Will be populated after deployment
55
+ }
56
+
57
+ url = endpoint_urls.get(endpoint)
58
+
59
+ if not url:
60
+ raise Exception(f"Unknown endpoint: {endpoint}")
61
+
62
+ # Build request payload
63
+ payload = {
64
+ 'credentials': credentials,
65
+ 'accounts': accounts
66
+ }
67
+ payload.update(kwargs)
68
+
69
+ # Make API call
70
+ headers = {
71
+ 'X-API-Secret': api_config['api_secret'],
72
+ 'Content-Type': 'application/json'
73
+ }
74
+
75
+ response = requests.post(url, headers=headers, json=payload, timeout=300)
76
+
77
+ if response.status_code != 200:
78
+ raise Exception(f"API call failed: {response.status_code} - {response.text}")
79
+
80
+ return response.json()
81
+
82
+
83
+ def is_api_configured():
84
+ """Check if API is configured."""
85
+ return get_api_config() is not None