Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This tutorial explains how you use a Python script to export Azure Carbon optimization emissions data as JSON output. The Python script runs Carbon Service REST API network requests to get emissions data for your Azure resources. The script simplifies the process of querying the API and handling the response. You run the script to generate the JSON files and then use them for detailed analysis and reporting.
This tutorial covers the steps needed to export carbon optimization emissions data on your local Windows computer.
There are several steps to complete this tutorial:
- Review prerequisites and install missing components
- Download and install Python
- Install required Python packages
- Examine and update the Python script example
- Run the Python script
- Review the JSON output files
Prerequisites
Before you use the Python script, ensure you have:
- Appropriate Azure permissions (
Carbon Optimization Reader,Subscription Owner, orSubscription Contributorrole)- For more information, see Assign Azure roles by using the Azure portal and Assign access to Carbon optimization in Azure.
- A list of valid Azure subscription IDs that you want to get emissions data for
- An understanding of carbon emission scopes (Scope1, Scope2, Scope3)
- At least one full month of emissions data available for export (data is available for the previous month by day 19 of the current month)
Install Azure PowerShell
If you don't have Azure PowerShell installed on your local Windows computer, follow these steps:
Launch Windows PowerShell 5.1 as an administrator and run the following command to update PowerShellGet by using the PowerShell gallery:
Install-Module -Name PowerShellGet -Force
Set the PowerShell execution policy to remote signed or less restrictive:
- Check the PowerShell execution policy:
Get-ExecutionPolicy -List - Set the PowerShell execution policy to remote signed:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Use the Install-Module cmdlet to install the Az PowerShell module:
Install-Module -Name Az -Repository PSGallery -Force
You might need to restart PowerShell after the installation is complete.
For more information about installing Azure PowerShell, including installation on different platforms, see How to install Azure PowerShell.
Sign in to Azure
To start managing your Azure resources with the Az PowerShell module, launch a PowerShell session and run Connect-AzAccount to sign in to Azure:
Connect-AzAccount
Use your Azure account sign in credentials to log into the browser window that opens.
You need to repeat this step for every new PowerShell session you start.
Install Azure CLI
If you don't have Azure CLI installed on your local Windows computer, follow these steps:
- Review the information at Install the Azure CLI on Windows.
- Choose an installation method and then run the installer that's best suited for your local computer.
- After installation completes, open a new command prompt or PowerShell window (with administrator privileges) sign in to your Azure account:
az login
Download and install Python
If you don't have Python installed on your local Windows computer, follow these steps:
- Review the information at Python downloads.
- Choose, download, and run the installer for a Python release that's best suited for your local computer.
Install required Python packages
In your command prompt or PowerShell window (with administrator privileges), run the following command to install the required Python packages:
pip install azure-identity azure-mgmt-carbonoptimization
Examine and update the Python script example
- Copy the following Python example script and save it locally. For example, save it as
export_carbon_emission_data.py - Review the script and replace all instances of
Subscription_ID_XXXwith your actual Azure subscription IDs. Add or remove example subscriptions, as necessary. Up to 100 subscription IDs are supported. - Save the file.
By default, the script only outputs data for the last full month. You can update the script for a custom time range (full months) for some reports. Review the script comments to see if a report supports a custom range. Look for instances of:
date_range = DateRange(
start=date.fromisoformat(available_date_range.start_date),
end=date.fromisoformat(available_date_range.end_date),
)
Then update like the following example:
date_range = DateRange(
start=date.fromisoformat("YYYY-MM-DD"),
end=date.fromisoformat("YYYY-MM-DD"),
)
"""
Azure Carbon Optimization
This script queries Azure Carbon Optimization reports by using the Python azure-mgmt-carbonoptimization(https://pypi.org/project/azure-mgmt-carbonoptimization/) SDK.
"""
import os
import json
import logging
import time
from datetime import datetime, timezone, date
from typing import List, Dict, Any, Optional
from pathlib import Path
from azure.identity import DefaultAzureCredential
from azure.mgmt.carbonoptimization import CarbonOptimizationMgmtClient
from azure.mgmt.carbonoptimization.models import CarbonEmissionDataAvailableDateRange, CategoryTypeEnum, SortDirectionEnum,\
OrderByColumnEnum, ReportTypeEnum, ResponseDataTypeEnum, CarbonEmissionItemDetailData, DateRange, EmissionScopeEnum,\
CarbonEmissionData, ResourceCarbonEmissionItemDetailData, ResourceGroupCarbonEmissionItemDetailData, \
ItemDetailsQueryFilter, MonthlySummaryReportQueryFilter, TopItemsSummaryReportQueryFilter, \
TopItemsMonthlySummaryReportQueryFilter, OverallSummaryReportQueryFilter, CarbonEmissionDataListResult
from azure.core.exceptions import (
ClientAuthenticationError,
HttpResponseError,
ResourceNotFoundError
)
# Initialize Azure CarbonOptimization SDK clients
credential = DefaultAzureCredential()
client = CarbonOptimizationMgmtClient(credential=credential)
carbon_service = client.carbon_service
def query_item_detail_data_by_category_type(category_type: CategoryTypeEnum) -> None :
# get latest available carbon data date range
available_date_range = carbon_service.query_carbon_emission_data_available_date_range()
# Get latest month
date_range = DateRange(
start=date.fromisoformat(available_date_range.end_date),
end=date.fromisoformat(available_date_range.end_date),
)
# Build query filter for item detail report
item_detail_query_filter = ItemDetailsQueryFilter(date_range=date_range,
subscription_list=[
"Subscription_ID_001", "Subscription_ID_002", "Subscription_ID_100"
], # suggest to put 100 subscription id
carbon_scope_list=[EmissionScopeEnum.SCOPE1, EmissionScopeEnum.SCOPE2, EmissionScopeEnum.SCOPE3],
category_type=category_type,
order_by=OrderByColumnEnum.ITEM_NAME,
sort_direction=SortDirectionEnum.DESC,
page_size=50 # suggest with 2000 as pageSize
)
with open(f"carbon_emission_{str(category_type.value).lower()}_item_detail_report.json", "a", encoding="utf-8") as f:
while True:
result_list = carbon_service.query_carbon_emission_reports(item_detail_query_filter)
for item in result_list.value:
f.write(json.dumps(item.as_dict(), ensure_ascii=False))
f.write("\n")
if not result_list.skip_token:
# no more pages, break
print("all data retrieved")
break
# set the continuation token for the next page
item_detail_query_filter.skip_token = result_list.skip_token
print("continue to get next page data")
def query_top_items_monthly_report_by_category_type(category_type: CategoryTypeEnum) -> None :
# get latest available carbon data date range
available_date_range = carbon_service.query_carbon_emission_data_available_date_range()
date_range = DateRange(
start=date.fromisoformat(available_date_range.start_date),
end=date.fromisoformat(available_date_range.end_date),
)
# Build query filter for top items monthly report
item_detail_query_filter = TopItemsMonthlySummaryReportQueryFilter(
date_range=date_range,
subscription_list=[
"Subscription_ID_001", "Subscription_ID_002", "Subscription_ID_100"
], # suggest to put 100 subscription id
carbon_scope_list=[EmissionScopeEnum.SCOPE1, EmissionScopeEnum.SCOPE2, EmissionScopeEnum.SCOPE3],
category_type=category_type,
top_items=5
)
with open(f"carbon_emission_{str(category_type.value).lower()}_top_items_monthly_report.json", "a", encoding="utf-8") as f:
result_list = carbon_service.query_carbon_emission_reports(item_detail_query_filter)
for item in result_list.value:
f.write(json.dumps(item.as_dict(), ensure_ascii=False))
f.write("\n")
def query_top_items_report_by_category_type(category_type: CategoryTypeEnum) -> None :
# get latest available carbon data date range
available_date_range = carbon_service.query_carbon_emission_data_available_date_range()
# only set one month for Top Items Report
date_range = DateRange(
start=date.fromisoformat(available_date_range.end_date),
end=date.fromisoformat(available_date_range.end_date),
)
# Build query filter for top items report
item_detail_query_filter = TopItemsSummaryReportQueryFilter(
date_range=date_range,
subscription_list=[
"Subscription_ID_001", "Subscription_ID_002", "Subscription_ID_100"
], # suggest to put 100 subscription id
carbon_scope_list=[EmissionScopeEnum.SCOPE1, EmissionScopeEnum.SCOPE2, EmissionScopeEnum.SCOPE3],
category_type=category_type,
top_items=5
)
with open(f"carbon_emission_{str(category_type.value).lower()}_top_items_report.json", "a", encoding="utf-8") as f:
result_list = carbon_service.query_carbon_emission_reports(item_detail_query_filter)
for item in result_list.value:
f.write(json.dumps(item.as_dict(), ensure_ascii=False))
f.write("\n")
def query_overall_summary_report_by_category_type() -> None :
# get latest available carbon data date range
available_date_range = carbon_service.query_carbon_emission_data_available_date_range()
date_range = DateRange(
start=date.fromisoformat(available_date_range.start_date),
end=date.fromisoformat(available_date_range.end_date),
)
# Build query filter for overall summary report
item_detail_query_filter = OverallSummaryReportQueryFilter(
date_range=date_range,
subscription_list=[
"Subscription_ID_001", "Subscription_ID_002", "Subscription_ID_100"
], # suggest to put 100 subscription id
carbon_scope_list=[EmissionScopeEnum.SCOPE1, EmissionScopeEnum.SCOPE2, EmissionScopeEnum.SCOPE3]
)
with open(f"carbon_emission_overall_summary_report.json", "a", encoding="utf-8") as f:
result_list = carbon_service.query_carbon_emission_reports(item_detail_query_filter)
for item in result_list.value:
f.write(json.dumps(item.as_dict(), ensure_ascii=False))
f.write("\n")
def query_monthly_overall_summary_report_by_category_type() -> None :
# get latest available carbon data date range
available_date_range = carbon_service.query_carbon_emission_data_available_date_range()
date_range = DateRange(
start=date.fromisoformat(available_date_range.start_date),
end=date.fromisoformat(available_date_range.end_date),
)
# Build query filter for monthly overall summary report
item_detail_query_filter = MonthlySummaryReportQueryFilter(
date_range=date_range,
subscription_list=[
"Subscription_ID_001", "Subscription_ID_002", "Subscription_ID_100"
], # suggest to put 100 subscription id
carbon_scope_list=[EmissionScopeEnum.SCOPE1, EmissionScopeEnum.SCOPE2, EmissionScopeEnum.SCOPE3]
)
with open(f"carbon_emission_monthly_overall_summary_report.json", "a", encoding="utf-8") as f:
result_list = carbon_service.query_carbon_emission_reports(item_detail_query_filter)
for item in result_list.value:
f.write(json.dumps(item.as_dict(), ensure_ascii=False))
f.write("\n")
def get_latest_available_carbon_data_date_range() -> CarbonEmissionDataAvailableDateRange:
"""
Query the latest available carbon data date range.
"""
available_date_range = carbon_service.query_carbon_emission_data_available_date_range()
print(f"Available date range: {available_date_range.start_date} to {available_date_range.end_date}")
return available_date_range
if __name__ == "__main__":
# get latest available carbon data date range
get_latest_available_carbon_data_date_range()
# get carbon emission item detail report
query_item_detail_data_by_category_type(CategoryTypeEnum.RESOURCE)
query_item_detail_data_by_category_type(CategoryTypeEnum.LOCATION)
query_item_detail_data_by_category_type(CategoryTypeEnum.RESOURCE_TYPE)
query_item_detail_data_by_category_type(CategoryTypeEnum.RESOURCE_GROUP)
query_item_detail_data_by_category_type(CategoryTypeEnum.SUBSCRIPTION)
# get top items monthly report
query_top_items_monthly_report_by_category_type(CategoryTypeEnum.RESOURCE)
query_top_items_monthly_report_by_category_type(CategoryTypeEnum.RESOURCE_GROUP)
query_top_items_monthly_report_by_category_type(CategoryTypeEnum.LOCATION)
query_top_items_monthly_report_by_category_type(CategoryTypeEnum.RESOURCE_TYPE)
query_top_items_monthly_report_by_category_type(CategoryTypeEnum.SUBSCRIPTION)
# get top items report
query_top_items_report_by_category_type(CategoryTypeEnum.RESOURCE)
query_top_items_report_by_category_type(CategoryTypeEnum.RESOURCE_GROUP)
query_top_items_report_by_category_type(CategoryTypeEnum.LOCATION)
query_top_items_report_by_category_type(CategoryTypeEnum.RESOURCE_TYPE)
query_top_items_report_by_category_type(CategoryTypeEnum.SUBSCRIPTION)
# get overall summary report
query_overall_summary_report_by_category_type()
# get monthly overall summary report
query_monthly_overall_summary_report_by_category_type()
Run the Python script
Run the Python script from your command prompt or PowerShell window (with administrator privileges):
python export_carbon_emission_data.py
JSON output files are created in the same directory as the script. The files are named by report type.
Here's a list of the output files that are created:
carbon_emission_location_item_detail_report.jsoncarbon_emission_location_top_items_monthly_report.jsoncarbon_emission_location_top_items_report.jsoncarbon_emission_monthly_overall_summary_report.jsoncarbon_emission_overall_summary_report.jsoncarbon_emission_resourcegroup_item_detail_report.jsoncarbon_emission_resourcegroup_top_items_monthly_report.jsoncarbon_emission_resourcegroup_top_items_report.jsoncarbon_emission_resourcetype_item_detail_report.jsoncarbon_emission_resourcetype_top_items_monthly_report.jsoncarbon_emission_resourcetype_top_items_report.jsoncarbon_emission_resource_item_detail_report.jsoncarbon_emission_resource_top_items_monthly_report.jsoncarbon_emission_resource_top_items_report.jsoncarbon_emission_subscription_item_detail_report.jsoncarbon_emission_subscription_top_items_monthly_report.jsoncarbon_emission_subscription_top_items_report.json
Review the JSON output files
Here's example output for the monthly overall summary report, from the carbon_emission_overall_summary_report.json file.
{"dataType": "OverallSummaryData", "latestMonthEmissions": 13871.2808902499, "previousMonthEmissions": 14007.1957894844, "monthOverMonthEmissionsChangeRatio": -0.00970321977912344, "monthlyEmissionsChangeValue": -135.91489923458}
For more information about the reports and the data they contain, see Export emissions API reference.