aztree 0.2.0__tar.gz
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.
- aztree-0.2.0/.gitignore +14 -0
- aztree-0.2.0/LICENSE +22 -0
- aztree-0.2.0/PKG-INFO +127 -0
- aztree-0.2.0/README.md +108 -0
- aztree-0.2.0/aztree/__init__.py +805 -0
- aztree-0.2.0/aztree/__main__.py +4 -0
- aztree-0.2.0/aztree/viewer.html +629 -0
- aztree-0.2.0/pyproject.toml +36 -0
- aztree-0.2.0/tests/test_aztree.py +1327 -0
aztree-0.2.0/.gitignore
ADDED
aztree-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Branko Petric
|
|
4
|
+
Copyright (c) 2026 Milan Milanović
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
aztree-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: aztree
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: See where your Azure money goes, as a treemap in one offline HTML page.
|
|
5
|
+
Project-URL: Homepage, https://github.com/milanm/aztree
|
|
6
|
+
Project-URL: Issues, https://github.com/milanm/aztree/issues
|
|
7
|
+
Author: Milan Milanović
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: azure,cost,cost-management,finops,treemap
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: System :: Systems Administration
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# aztree
|
|
21
|
+
|
|
22
|
+
**Where did my Azure money go?** aztree reads your Azure costs and draws them as a treemap: big box, big cost. It's a port of [awstree](https://github.com/petricbranko/awstree) by Branko Petric, which took the idea from [disktree](https://x.com/tobi/status/2103251521223921739) by [Tobi Lütke](https://x.com/tobi). Same idea again, pointed at an Azure subscription.
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
It's one small Python package with no dependencies, and it produces a single HTML page that works offline.
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pipx install aztree # or: pip install aztree
|
|
32
|
+
aztree --demo # try it with fake data, no Azure needed
|
|
33
|
+
az login
|
|
34
|
+
aztree # your current subscription
|
|
35
|
+
aztree --all # every subscription you can see
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Before the first PyPI release, install from GitHub instead: `pipx install git+https://github.com/milanm/aztree`. From a clone, run `python -m aztree` without installing anything.
|
|
39
|
+
|
|
40
|
+
The page opens in your browser. It shows the last 30 days, compared with the 30 days before. The last day is the day before yesterday, because Azure is still posting yesterday's usage.
|
|
41
|
+
|
|
42
|
+
## What you get
|
|
43
|
+
|
|
44
|
+
- **Treemap** of spend by service → meter. Press `2` to group by subscription, `3` by region and `4` by resource group → resource.
|
|
45
|
+
- **Color by change** (`c`): red where spend grew, green where it shrank.
|
|
46
|
+
- **Selection panel:** cost, share of the bill, change vs the previous period, monthly pace and a daily chart.
|
|
47
|
+
- **Worth a look:** the fastest-growing costs, plus known Azure money pits (Log Analytics ingestion, data transfer out, NAT and Firewall data processing, Basic and static public IPs, disk snapshots, previous-generation VM sizes, Premium v2 App Service plans and Extended Security Updates).
|
|
48
|
+
- **Biggest drops:** what fell since the previous period, including anything that went to zero, so you can see a saving land.
|
|
49
|
+
- **Advisor:** Azure Advisor's cost recommendations (reservations, savings plans, right-sizing), one per resource and SKU. Click one to jump to the resource or subscription it's about.
|
|
50
|
+
- **Export for AI:** a JSON summary to hand to any AI agent (see below).
|
|
51
|
+
|
|
52
|
+
Click to select, double-click to zoom in, `⌫` to go back up, `/` to filter. Add `#resource`, `#subscription` or `#region` to the page's URL to open that view.
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
|
|
56
|
+
- Python 3.9+ and the [Azure CLI](https://aka.ms/azcli), logged in with `az login`. Without the CLI, put a token for `https://management.azure.com/` in `AZURE_ACCESS_TOKEN` and name the subscriptions with `--subscription` or `--all`. A bare token only sees its own tenant; through the CLI, aztree sees every tenant you're logged in to and gets a token for each.
|
|
57
|
+
- The **Cost Management Reader** role (or Reader) on each subscription. Advisor tips need Reader; without it you still get the page.
|
|
58
|
+
- Tested on a CSP subscription. On CSP, Azure shows costs at retail prices without your partner's discounts, and reserved usage as $0 even with `--metric AmortizedCost`, so the totals won't match your partner's invoice. Pay-as-you-go and Visual Studio subscriptions use the same API.
|
|
59
|
+
- EA and MCA billing scopes should work through `--scope`, but nobody has tried yet. At such a scope the subscription view shows the whole scope as one box, and Advisor is skipped.
|
|
60
|
+
|
|
61
|
+
**Cost:** Cost Management queries are free. Azure throttles them per subscription and per tenant, so a run makes about 8–10 requests per subscription and may wait 30–60 seconds when Azure asks it to. aztree saves the data in `~/.aztree/`, so reopening the page is instant:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
aztree --from
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Ask an AI about your bill
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
aztree --from --export
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This writes `~/.aztree/aztree-export.json`, a compact summary that includes instructions for the agent. It has totals, breakdowns by service, subscription, region and resource group, and every meter with its change vs the previous period. It also lists the top growers and drops, credits and refunds, the flagged money pits and the Advisor tips. Give it to an AI agent and ask *"where can I save money?"*. The **Export for AI** button in the page (or `e`) downloads the same file.
|
|
74
|
+
|
|
75
|
+
## Options
|
|
76
|
+
|
|
77
|
+
| Flag | What it does |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `--demo` | Fake data, no Azure access needed |
|
|
80
|
+
| `--subscription ID_OR_NAME` | Subscription to read; repeat for more. Default: the Azure CLI's current one |
|
|
81
|
+
| `--all` | Every enabled subscription you can see, in every tenant you're logged in to |
|
|
82
|
+
| `--scope SCOPE` | Any Cost Management scope, e.g. `/providers/Microsoft.Billing/billingAccounts/ID` (untested) |
|
|
83
|
+
| `--days N` | Period length, default 30. It's always compared with the period before it. |
|
|
84
|
+
| `--metric M` | `ActualCost` (default) or `AmortizedCost` |
|
|
85
|
+
| `--no-advisor` | Skip Azure Advisor |
|
|
86
|
+
| `--from [FILE]` | Reopen saved data without calling Azure (default: the last run) |
|
|
87
|
+
| `--export [FILE]` | Write the AI summary JSON instead of the page (default `~/.aztree/aztree-export.json`) |
|
|
88
|
+
| `--out FILE` | Where to write the page (default `~/.aztree/aztree.html`) |
|
|
89
|
+
| `--no-open` | Don't open the browser |
|
|
90
|
+
| `--verbose` | Print pages, rows and query units per request |
|
|
91
|
+
| `--version` | Print the version |
|
|
92
|
+
|
|
93
|
+
## Good to know
|
|
94
|
+
|
|
95
|
+
- `ActualCost` books a reservation or savings plan purchase as one lump on the day you bought it. `--metric AmortizedCost` spreads it over the term.
|
|
96
|
+
- Credits and refunds count in the totals, but negative amounts can't be drawn as boxes. The header says how much of the total they are.
|
|
97
|
+
- Subscriptions that bill in different currencies are drawn in USD.
|
|
98
|
+
- If a subscription has so many resources that a daily breakdown takes more than ten pages of results, the resource view still lists every resource but with one total per period and no daily chart.
|
|
99
|
+
- Marketplace charges keep their publisher's meter names and get no special handling.
|
|
100
|
+
- Runs save to `~/.aztree/`; set `AZTREE_HOME` to move it. Older versions run from a clone saved to `out/`, and `aztree --from out/aztree-data.json` still opens those runs.
|
|
101
|
+
|
|
102
|
+
## Checking against the portal
|
|
103
|
+
|
|
104
|
+
In the Azure portal, open **Cost Management → Cost analysis**, choose the cost type you ran with (**Actual cost** by default), daily granularity and the dates in aztree's header. The totals should match to the cent. Azure can still add a little to the last day after aztree reads it, so compare soon after a run.
|
|
105
|
+
|
|
106
|
+
## Privacy
|
|
107
|
+
|
|
108
|
+
aztree only reads cost data and Advisor recommendations, and never changes anything in your subscriptions. Everything it writes goes to `~/.aztree/` (or `AZTREE_HOME`), outside any git repo, because it contains your subscription IDs and costs. The page loads nothing from the internet. Share the HTML or export file only with people who should see your bill.
|
|
109
|
+
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python -m unittest discover -s tests
|
|
114
|
+
python -m aztree --demo
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The tests need no Azure access. The viewer tests run the page's script in Node and are skipped without it.
|
|
118
|
+
|
|
119
|
+
## Credits
|
|
120
|
+
|
|
121
|
+
aztree is a port of [awstree](https://github.com/petricbranko/awstree) by Branko Petric (MIT). It keeps awstree's viewer and its JSON contract and replaces the AWS parts. awstree, in turn, is inspired by [disktree](https://x.com/tobi/status/2103251521223921739) by [Tobi Lütke](https://x.com/tobi).
|
|
122
|
+
|
|
123
|
+
aztree is not affiliated with or endorsed by Microsoft.
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
[MIT](LICENSE)
|
aztree-0.2.0/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# aztree
|
|
2
|
+
|
|
3
|
+
**Where did my Azure money go?** aztree reads your Azure costs and draws them as a treemap: big box, big cost. It's a port of [awstree](https://github.com/petricbranko/awstree) by Branko Petric, which took the idea from [disktree](https://x.com/tobi/status/2103251521223921739) by [Tobi Lütke](https://x.com/tobi). Same idea again, pointed at an Azure subscription.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
It's one small Python package with no dependencies, and it produces a single HTML page that works offline.
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pipx install aztree # or: pip install aztree
|
|
13
|
+
aztree --demo # try it with fake data, no Azure needed
|
|
14
|
+
az login
|
|
15
|
+
aztree # your current subscription
|
|
16
|
+
aztree --all # every subscription you can see
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Before the first PyPI release, install from GitHub instead: `pipx install git+https://github.com/milanm/aztree`. From a clone, run `python -m aztree` without installing anything.
|
|
20
|
+
|
|
21
|
+
The page opens in your browser. It shows the last 30 days, compared with the 30 days before. The last day is the day before yesterday, because Azure is still posting yesterday's usage.
|
|
22
|
+
|
|
23
|
+
## What you get
|
|
24
|
+
|
|
25
|
+
- **Treemap** of spend by service → meter. Press `2` to group by subscription, `3` by region and `4` by resource group → resource.
|
|
26
|
+
- **Color by change** (`c`): red where spend grew, green where it shrank.
|
|
27
|
+
- **Selection panel:** cost, share of the bill, change vs the previous period, monthly pace and a daily chart.
|
|
28
|
+
- **Worth a look:** the fastest-growing costs, plus known Azure money pits (Log Analytics ingestion, data transfer out, NAT and Firewall data processing, Basic and static public IPs, disk snapshots, previous-generation VM sizes, Premium v2 App Service plans and Extended Security Updates).
|
|
29
|
+
- **Biggest drops:** what fell since the previous period, including anything that went to zero, so you can see a saving land.
|
|
30
|
+
- **Advisor:** Azure Advisor's cost recommendations (reservations, savings plans, right-sizing), one per resource and SKU. Click one to jump to the resource or subscription it's about.
|
|
31
|
+
- **Export for AI:** a JSON summary to hand to any AI agent (see below).
|
|
32
|
+
|
|
33
|
+
Click to select, double-click to zoom in, `⌫` to go back up, `/` to filter. Add `#resource`, `#subscription` or `#region` to the page's URL to open that view.
|
|
34
|
+
|
|
35
|
+
## Requirements
|
|
36
|
+
|
|
37
|
+
- Python 3.9+ and the [Azure CLI](https://aka.ms/azcli), logged in with `az login`. Without the CLI, put a token for `https://management.azure.com/` in `AZURE_ACCESS_TOKEN` and name the subscriptions with `--subscription` or `--all`. A bare token only sees its own tenant; through the CLI, aztree sees every tenant you're logged in to and gets a token for each.
|
|
38
|
+
- The **Cost Management Reader** role (or Reader) on each subscription. Advisor tips need Reader; without it you still get the page.
|
|
39
|
+
- Tested on a CSP subscription. On CSP, Azure shows costs at retail prices without your partner's discounts, and reserved usage as $0 even with `--metric AmortizedCost`, so the totals won't match your partner's invoice. Pay-as-you-go and Visual Studio subscriptions use the same API.
|
|
40
|
+
- EA and MCA billing scopes should work through `--scope`, but nobody has tried yet. At such a scope the subscription view shows the whole scope as one box, and Advisor is skipped.
|
|
41
|
+
|
|
42
|
+
**Cost:** Cost Management queries are free. Azure throttles them per subscription and per tenant, so a run makes about 8–10 requests per subscription and may wait 30–60 seconds when Azure asks it to. aztree saves the data in `~/.aztree/`, so reopening the page is instant:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
aztree --from
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Ask an AI about your bill
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
aztree --from --export
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This writes `~/.aztree/aztree-export.json`, a compact summary that includes instructions for the agent. It has totals, breakdowns by service, subscription, region and resource group, and every meter with its change vs the previous period. It also lists the top growers and drops, credits and refunds, the flagged money pits and the Advisor tips. Give it to an AI agent and ask *"where can I save money?"*. The **Export for AI** button in the page (or `e`) downloads the same file.
|
|
55
|
+
|
|
56
|
+
## Options
|
|
57
|
+
|
|
58
|
+
| Flag | What it does |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `--demo` | Fake data, no Azure access needed |
|
|
61
|
+
| `--subscription ID_OR_NAME` | Subscription to read; repeat for more. Default: the Azure CLI's current one |
|
|
62
|
+
| `--all` | Every enabled subscription you can see, in every tenant you're logged in to |
|
|
63
|
+
| `--scope SCOPE` | Any Cost Management scope, e.g. `/providers/Microsoft.Billing/billingAccounts/ID` (untested) |
|
|
64
|
+
| `--days N` | Period length, default 30. It's always compared with the period before it. |
|
|
65
|
+
| `--metric M` | `ActualCost` (default) or `AmortizedCost` |
|
|
66
|
+
| `--no-advisor` | Skip Azure Advisor |
|
|
67
|
+
| `--from [FILE]` | Reopen saved data without calling Azure (default: the last run) |
|
|
68
|
+
| `--export [FILE]` | Write the AI summary JSON instead of the page (default `~/.aztree/aztree-export.json`) |
|
|
69
|
+
| `--out FILE` | Where to write the page (default `~/.aztree/aztree.html`) |
|
|
70
|
+
| `--no-open` | Don't open the browser |
|
|
71
|
+
| `--verbose` | Print pages, rows and query units per request |
|
|
72
|
+
| `--version` | Print the version |
|
|
73
|
+
|
|
74
|
+
## Good to know
|
|
75
|
+
|
|
76
|
+
- `ActualCost` books a reservation or savings plan purchase as one lump on the day you bought it. `--metric AmortizedCost` spreads it over the term.
|
|
77
|
+
- Credits and refunds count in the totals, but negative amounts can't be drawn as boxes. The header says how much of the total they are.
|
|
78
|
+
- Subscriptions that bill in different currencies are drawn in USD.
|
|
79
|
+
- If a subscription has so many resources that a daily breakdown takes more than ten pages of results, the resource view still lists every resource but with one total per period and no daily chart.
|
|
80
|
+
- Marketplace charges keep their publisher's meter names and get no special handling.
|
|
81
|
+
- Runs save to `~/.aztree/`; set `AZTREE_HOME` to move it. Older versions run from a clone saved to `out/`, and `aztree --from out/aztree-data.json` still opens those runs.
|
|
82
|
+
|
|
83
|
+
## Checking against the portal
|
|
84
|
+
|
|
85
|
+
In the Azure portal, open **Cost Management → Cost analysis**, choose the cost type you ran with (**Actual cost** by default), daily granularity and the dates in aztree's header. The totals should match to the cent. Azure can still add a little to the last day after aztree reads it, so compare soon after a run.
|
|
86
|
+
|
|
87
|
+
## Privacy
|
|
88
|
+
|
|
89
|
+
aztree only reads cost data and Advisor recommendations, and never changes anything in your subscriptions. Everything it writes goes to `~/.aztree/` (or `AZTREE_HOME`), outside any git repo, because it contains your subscription IDs and costs. The page loads nothing from the internet. Share the HTML or export file only with people who should see your bill.
|
|
90
|
+
|
|
91
|
+
## Development
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python -m unittest discover -s tests
|
|
95
|
+
python -m aztree --demo
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The tests need no Azure access. The viewer tests run the page's script in Node and are skipped without it.
|
|
99
|
+
|
|
100
|
+
## Credits
|
|
101
|
+
|
|
102
|
+
aztree is a port of [awstree](https://github.com/petricbranko/awstree) by Branko Petric (MIT). It keeps awstree's viewer and its JSON contract and replaces the AWS parts. awstree, in turn, is inspired by [disktree](https://x.com/tobi/status/2103251521223921739) by [Tobi Lütke](https://x.com/tobi).
|
|
103
|
+
|
|
104
|
+
aztree is not affiliated with or endorsed by Microsoft.
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
[MIT](LICENSE)
|