자습서: Python 스크립트를 사용하여 탄소 최적화 데이터 내보내기

이 자습서에서는 Python 스크립트를 사용하여 Azure 탄소 최적화 배출 데이터를 JSON 출력으로 내보내는 방법을 설명합니다. Python 스크립트는 Azure 리소스에 대한 배출 데이터를 가져오기 위해 Carbon Service REST API 네트워크 요청을 실행합니다. 스크립트는 API를 쿼리하고 응답을 처리하는 프로세스를 간소화합니다. 스크립트를 실행하여 JSON 파일을 생성한 다음 자세한 분석 및 보고에 사용합니다.

이 자습서에서는 로컬 Windows 컴퓨터에서 탄소 최적화 배출 데이터를 내보내는 데 필요한 단계를 설명합니다.

이 자습서를 완료하는 몇 가지 단계가 있습니다.

  • 필수 구성 요소를 검토하고 누락된 구성 요소 설치
  • Python 다운로드 및 설치
  • 필요한 Python 패키지 설치
  • Python 스크립트 예제 검사 및 업데이트
  • Python 스크립트 실행
  • JSON 출력 파일 검토

필수 조건

Python 스크립트를 사용하기 전에 다음이 있는지 확인합니다.

  • 적절한 Azure 권한(Carbon Optimization Reader, Subscription Owner, 또는 Subscription Contributor 역할)
  • 배출 데이터를 가져올 유효한 Azure 구독 ID 목록
  • 탄소 배출 범위에 대한 이해(Scope1, Scope2, Scope3)
  • 내보내는 데 사용할 수 있는 최소 한 달의 배출 데이터(데이터는 현재 월의 19일째까지 이전 달에 사용할 수 있음)

Azure PowerShell 설치

로컬 Windows 컴퓨터에 Azure PowerShell이 설치되어 있지 않은 경우 다음 단계를 수행합니다.

관리자 권한으로 Windows PowerShell 5.1을 시작하고 다음 명령을 실행하여 PowerShell 갤러리를 사용하여 PowerShellGet을 업데이트합니다.

Install-Module -Name PowerShellGet -Force

PowerShell 실행 정책을 원격 서명되거나 덜 제한적인 정책으로 설정합니다.

  • PowerShell 실행 정책을 확인합니다.
    Get-ExecutionPolicy -List
    
  • PowerShell 실행 정책을 원격 서명됨으로 설정합니다.
    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
    
    

Install-Module cmdlet을 사용하여 Az PowerShell 모듈을 설치합니다.

Install-Module -Name Az -Repository PSGallery -Force

설치가 완료된 후 PowerShell을 다시 시작해야 할 수 있습니다.

다른 플랫폼에 설치를 포함하여 Azure PowerShell을 설치하는 방법에 대한 자세한 내용은 Azure PowerShell을 설치하는 방법을 참조하세요.

Azure에 로그인

Az PowerShell 모듈을 사용하여 Azure 리소스 관리를 시작하려면 PowerShell 세션을 시작하고 실행 Connect-AzAccount 하여 Azure에 로그인합니다.

Connect-AzAccount

Azure 계정 로그인 자격 증명을 사용하여 열리는 브라우저 창에 로그인합니다.

시작하는 모든 새 PowerShell 세션에 대해 이 단계를 반복해야 합니다.

Azure CLI 설치

로컬 Windows 컴퓨터에 Azure CLI가 설치되어 있지 않은 경우 다음 단계를 수행합니다.

  1. Windows에 Azure CLI 설치 시 정보를 검토합니다.
  2. 설치 방법을 선택한 다음 로컬 컴퓨터에 가장 적합한 설치 관리자를 실행합니다.
  3. 설치가 완료되면 새 명령 프롬프트 또는 PowerShell 창(관리자 권한 포함)을 열고 Azure 계정에 로그인합니다.
    az login
    

Python 다운로드 및 설치

로컬 Windows 컴퓨터에 Python이 설치되어 있지 않은 경우 다음 단계를 수행합니다.

  1. Python 다운로드에서 정보를 검토합니다.
  2. 로컬 컴퓨터에 가장 적합한 Python 릴리스의 설치 관리자를 선택, 다운로드 및 실행합니다.

필요한 Python 패키지 설치

명령 프롬프트 또는 PowerShell 창(관리자 권한 사용)에서 다음 명령을 실행하여 필요한 Python 패키지를 설치합니다.

pip install azure-identity azure-mgmt-carbonoptimization

Python 스크립트 예제 검사 및 업데이트

  1. 다음 Python 예제 스크립트를 복사하고 로컬로 저장합니다. 예를 들어 다음으로 저장합니다. export_carbon_emission_data.py
  2. 스크립트를 검토하고 모든 인스턴스를 Subscription_ID_XXX 실제 Azure 구독 ID로 바꿉니다. 필요에 따라 예제 구독을 추가하거나 제거합니다. 최대 100개의 구독 ID가 지원됩니다.
  3. 파일을 저장합니다.

기본적으로 스크립트는 지난 한 달 동안의 데이터만 출력합니다. 일부 보고서의 사용자 지정 시간 범위(전체 개월)에 대한 스크립트를 업데이트할 수 있습니다. 스크립트 주석을 검토하여 보고서에서 사용자 지정 범위를 지원하는지 확인합니다. 다음의 인스턴스를 찾습니다.

    date_range = DateRange(
        start=date.fromisoformat(available_date_range.start_date),
        end=date.fromisoformat(available_date_range.end_date),
    )

그런 다음, 다음 예제와 같이 업데이트합니다.

    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()

Python 스크립트 실행

관리자 권한으로 명령 프롬프트 또는 PowerShell 창에서 Python 스크립트를 실행합니다.

python export_carbon_emission_data.py

JSON 출력 파일은 스크립트와 동일한 디렉터리에 만들어집니다. 파일의 이름은 보고서 유형별로 지정됩니다.

생성된 출력 파일의 목록은 다음과 같습니다.

  • carbon_emission_location_item_detail_report.json
  • carbon_emission_location_top_items_monthly_report.json
  • carbon_emission_location_top_items_report.json
  • carbon_emission_monthly_overall_summary_report.json
  • carbon_emission_overall_summary_report.json
  • carbon_emission_resourcegroup_item_detail_report.json
  • carbon_emission_resourcegroup_top_items_monthly_report.json
  • carbon_emission_resourcegroup_top_items_report.json
  • carbon_emission_resourcetype_item_detail_report.json
  • carbon_emission_resourcetype_top_items_monthly_report.json
  • carbon_emission_resourcetype_top_items_report.json
  • carbon_emission_resource_item_detail_report.json
  • carbon_emission_resource_top_items_monthly_report.json
  • carbon_emission_resource_top_items_report.json
  • carbon_emission_subscription_item_detail_report.json
  • carbon_emission_subscription_top_items_monthly_report.json
  • carbon_emission_subscription_top_items_report.json

JSON 출력 파일 검토

다음은 carbon_emission_overall_summary_report.json 파일의 월별 전체 요약 보고서에 대한 예제 출력입니다.

{"dataType": "OverallSummaryData", "latestMonthEmissions": 13871.2808902499, "previousMonthEmissions": 14007.1957894844, "monthOverMonthEmissionsChangeRatio": -0.00970321977912344, "monthlyEmissionsChangeValue": -135.91489923458}

보고서 및 포함된 데이터에 대한 자세한 내용은 내보내기 API 참조를 참조하세요.

다음 단계