CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-azure-mgmt-costmanagement

Microsoft Azure Cost Management Client Library for Python providing comprehensive access to cost analysis, billing data, budgets, alerts, exports, and recommendations.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

dimensions.mddocs/

Dimensions and Metadata

Query available cost dimensions for building filters and groupings in cost analysis. Access comprehensive metadata about available cost categories, resource types, billing dimensions, and hierarchy information to construct precise cost queries and reports.

Capabilities

Dimension Querying

Query and discover available dimensions for cost analysis, filtering, and grouping operations within specified scopes.

def list(
    scope: str,
    filter: str = None,
    expand: str = None,
    skiptoken: str = None,
    top: int = None
) -> DimensionsListResult:
    """
    List dimensions available for the specified scope.
    
    Args:
        scope (str): The scope to query dimensions for
        filter (str): OData filter expression for filtering dimensions
        expand (str): Expand options for additional dimension properties
        skiptoken (str): Skiptoken for pagination
        top (int): Maximum number of dimensions to return
    
    Returns:
        DimensionsListResult: Collection of available dimensions with metadata
    """

def by_external_cloud_provider_type(
    external_cloud_provider_type: str,
    external_cloud_provider_id: str,
    filter: str = None,
    expand: str = None,
    skiptoken: str = None,
    top: int = None
) -> DimensionsListResult:
    """
    List dimensions for external cloud providers like AWS.
    
    Args:
        external_cloud_provider_type (str): Provider type (e.g., "aws")
        external_cloud_provider_id (str): Provider account identifier
        filter (str): OData filter expression
        expand (str): Expand options for additional properties
        skiptoken (str): Skiptoken for pagination
        top (int): Maximum number of dimensions to return
    
    Returns:
        DimensionsListResult: Collection of external provider dimensions
    """

Usage Examples

Discover Available Dimensions

# Get all available dimensions for subscription
scope = "/subscriptions/{subscription-id}"
dimensions = client.dimensions.list(scope=scope)

print(f"Available dimensions ({len(dimensions.value)}):")
for dimension in dimensions.value:
    print(f"  Name: {dimension.name}")
    print(f"  Display Name: {dimension.display_name}")
    print(f"  Category: {dimension.category}")
    print(f"  Description: {dimension.description}")
    print(f"  Filter Enabled: {dimension.filter_enabled}")
    print(f"  Grouping Enabled: {dimension.grouping_enabled}")
    print("  ---")

Filter Dimensions by Category

# Get only resource-related dimensions
resource_filter = "category eq 'Resource'"
resource_dimensions = client.dimensions.list(
    scope=scope,
    filter=resource_filter
)

print("Resource Dimensions:")
for dimension in resource_dimensions.value:
    print(f"  {dimension.name}: {dimension.display_name}")
    if dimension.data:
        print(f"    Sample values: {dimension.data[:5]}")  # Show first 5 values

# Get billing-related dimensions
billing_filter = "category eq 'Billing'"
billing_dimensions = client.dimensions.list(
    scope=scope,
    filter=billing_filter
)

print("\nBilling Dimensions:")
for dimension in billing_dimensions.value:
    print(f"  {dimension.name}: {dimension.display_name}")

Explore Dimension Values

# Get dimensions with expanded data (actual values)
expanded_dimensions = client.dimensions.list(
    scope=scope,
    expand="data",
    top=10  # Limit for performance
)

print("Dimensions with sample values:")
for dimension in expanded_dimensions.value:
    print(f"\n{dimension.display_name} ({dimension.name}):")
    print(f"  Category: {dimension.category}")
    print(f"  Can Filter: {dimension.filter_enabled}")
    print(f"  Can Group: {dimension.grouping_enabled}")
    
    if hasattr(dimension, 'data') and dimension.data:
        print(f"  Sample values ({len(dimension.data)} total):")
        for value in dimension.data[:10]:  # Show first 10 values
            print(f"    - {value}")
        if len(dimension.data) > 10:
            print(f"    ... and {len(dimension.data) - 10} more")
    else:
        print("  Values: Use in query to see available values")

Build Dynamic Query Filters

from azure.mgmt.costmanagement.models import (
    QueryDefinition,
    QueryDataset,
    QueryFilter,
    QueryComparisonExpression,
    QueryOperatorType,
    TimeframeType,
    GranularityType
)

# Get resource group dimension values to build filter
rg_dimensions = client.dimensions.list(
    scope=scope,
    filter="name eq 'ResourceGroup'",
    expand="data"
)

if rg_dimensions.value:
    rg_dimension = rg_dimensions.value[0]
    
    # Use first few resource groups for filtering
    if rg_dimension.data and len(rg_dimension.data) > 0:
        selected_rgs = rg_dimension.data[:3]  # Select first 3 resource groups
        
        # Build query with dynamic filter
        query_filter = QueryFilter(
            and_=[
                QueryComparisonExpression(
                    name="ResourceGroup",
                    operator=QueryOperatorType.IN,
                    values=selected_rgs
                )
            ]
        )
        
        # Create query using discovered dimensions
        query_def = QueryDefinition(
            type="Usage",
            timeframe=TimeframeType.THE_LAST_MONTH,
            dataset=QueryDataset(
                granularity=GranularityType.DAILY,
                filter=query_filter
            )
        )
        
        # Execute query
        result = client.query.usage(scope, query_def)
        print(f"Query returned {len(result.rows)} rows for RGs: {', '.join(selected_rgs)}")

Analyze Dimension Capabilities

# Categorize dimensions by capabilities
filterable_dims = []
groupable_dims = []
both_dims = []

all_dimensions = client.dimensions.list(scope=scope)

for dimension in all_dimensions.value:
    if dimension.filter_enabled and dimension.grouping_enabled:
        both_dims.append(dimension)
    elif dimension.filter_enabled:
        filterable_dims.append(dimension)
    elif dimension.grouping_enabled:
        groupable_dims.append(dimension)

print(f"Dimension Capabilities Analysis:")
print(f"  Filter + Group capable: {len(both_dims)} dimensions")
print(f"  Filter only: {len(filterable_dims)} dimensions")
print(f"  Group only: {len(groupable_dims)} dimensions")

print(f"\nRecommended dimensions for analysis (Filter + Group):")
for dim in both_dims[:10]:  # Show top 10
    print(f"  - {dim.display_name} ({dim.name})")

Query External Cloud Provider Dimensions

# Get AWS dimensions
try:
    aws_dimensions = client.dimensions.by_external_cloud_provider_type(
        external_cloud_provider_type="aws",
        external_cloud_provider_id="123456789012"
    )
    
    print("AWS Dimensions:")
    for dimension in aws_dimensions.value:
        print(f"  {dimension.name}: {dimension.display_name}")
        print(f"    Category: {dimension.category}")
        print(f"    Filterable: {dimension.filter_enabled}")
        print(f"    Groupable: {dimension.grouping_enabled}")

except Exception as e:
    print(f"Error retrieving AWS dimensions: {e}")

Build Comprehensive Dimension Catalog

# Create a comprehensive catalog of dimensions
def build_dimension_catalog(scope):
    """Build a comprehensive catalog of available dimensions"""
    
    catalog = {
        "resource": [],
        "billing": [],
        "service": [],
        "location": [],
        "other": []
    }
    
    dimensions = client.dimensions.list(scope=scope, expand="data")
    
    for dimension in dimensions.value:
        dim_info = {
            "name": dimension.name,
            "display_name": dimension.display_name,
            "category": dimension.category,
            "filterable": dimension.filter_enabled,
            "groupable": dimension.grouping_enabled,
            "description": getattr(dimension, 'description', 'No description'),
            "sample_values": dimension.data[:5] if hasattr(dimension, 'data') and dimension.data else []
        }
        
        # Categorize by common patterns
        name_lower = dimension.name.lower()
        if 'resource' in name_lower:
            catalog["resource"].append(dim_info)
        elif 'billing' in name_lower or 'invoice' in name_lower:
            catalog["billing"].append(dim_info)
        elif 'service' in name_lower or 'meter' in name_lower:
            catalog["service"].append(dim_info)
        elif 'location' in name_lower or 'region' in name_lower:
            catalog["location"].append(dim_info)
        else:
            catalog["other"].append(dim_info)
    
    return catalog

# Build and display catalog
dimension_catalog = build_dimension_catalog(scope)

for category, dims in dimension_catalog.items():
    if dims:
        print(f"\n{category.upper()} DIMENSIONS ({len(dims)}):")
        for dim in dims:
            print(f"  {dim['display_name']}")
            print(f"    Name: {dim['name']}")
            print(f"    Capabilities: {'Filter' if dim['filterable'] else ''} {'Group' if dim['groupable'] else ''}")
            if dim['sample_values']:
                print(f"    Samples: {', '.join(dim['sample_values'])}")

Use Dimensions for Dynamic Report Building

# Build a dynamic cost report using discovered dimensions
def create_dynamic_report(scope, groupby_dimension="ResourceGroup"):
    """Create a cost report using a specified dimension for grouping"""
    
    # Verify dimension exists and supports grouping
    dimensions = client.dimensions.list(
        scope=scope,
        filter=f"name eq '{groupby_dimension}'"
    )
    
    if not dimensions.value:
        print(f"Dimension '{groupby_dimension}' not found")
        return None
        
    dimension = dimensions.value[0]
    if not dimension.grouping_enabled:
        print(f"Dimension '{groupby_dimension}' does not support grouping")
        return None
    
    # Create query using the dimension
    from azure.mgmt.costmanagement.models import QueryGrouping, QueryAggregation
    
    query_def = QueryDefinition(
        type="ActualCost",
        timeframe=TimeframeType.THE_LAST_MONTH,
        dataset=QueryDataset(
            granularity=GranularityType.MONTHLY,
            aggregation={
                "totalCost": QueryAggregation(name="Cost", function="Sum")
            },
            grouping=[
                QueryGrouping(type="Dimension", name=groupby_dimension)
            ]
        )
    )
    
    result = client.query.usage(scope, query_def)
    
    print(f"Cost Report by {dimension.display_name}:")
    for row in result.rows:
        group_value = row[0]
        cost = row[1]
        print(f"  {group_value}: ${cost:.2f}")
    
    return result

# Create reports using different dimensions
create_dynamic_report(scope, "ResourceGroup")
create_dynamic_report(scope, "ServiceName")
create_dynamic_report(scope, "Location")

Data Models

class Dimension:
    id: str
    name: str
    type: str
    category: str
    display_name: str
    description: str
    filter_enabled: bool
    grouping_enabled: bool
    sort_enabled: bool
    data: List[str]
    total: int
    next_link: str

class DimensionsListResult:
    value: List[Dimension]
    next_link: str

Dimension Categories

The Azure Cost Management API provides dimensions across several categories:

Resource Dimensions

  • ResourceGroup - Azure resource group names
  • ResourceType - Azure resource types (e.g., Microsoft.Compute/virtualMachines)
  • ResourceLocation - Azure regions and locations
  • ResourceId - Full Azure resource identifiers
  • ResourceGuid - Unique resource identifiers

Service Dimensions

  • ServiceName - Azure service names (e.g., Virtual Machines, Storage)
  • ServiceTier - Service tiers and SKUs
  • MeterCategory - Billing meter categories
  • MeterSubcategory - Billing meter subcategories
  • MeterName - Specific billing meters
  • Product - Product names and offerings

Billing Dimensions

  • BillingAccountId - Billing account identifiers
  • BillingProfileId - Billing profile identifiers
  • InvoiceId - Invoice identifiers
  • BillingPeriod - Billing period information
  • ChargeType - Type of charges (Usage, Purchase, etc.)

Organizational Dimensions

  • SubscriptionId - Azure subscription identifiers
  • SubscriptionName - Azure subscription names
  • DepartmentName - EA department names
  • AccountName - EA account names
  • CostCenter - Cost center assignments

Tag Dimensions

  • Tags - Resource tag keys and values for custom grouping and filtering

This module provides comprehensive dimension discovery capabilities for building sophisticated cost analysis queries with precise filtering, grouping, and categorization across all Azure billing and resource metadata.

Install with Tessl CLI

npx tessl i tessl/pypi-azure-mgmt-costmanagement

docs

alerts.md

benefits.md

dimensions.md

exports.md

index.md

price-sheet.md

query-forecast.md

reports.md

scheduled-actions.md

views.md

tile.json