Azure Retail Prices REST API 分析全 Azure 服务价格差异 - JSON 转 Excel版本

笔者有以下分析需求

  • 想知道同样服务所有区域的价格从低到高
  • 想知道同样服务那些区域有支援

这边可以使用 Azure Retail Prices REST API 达到目的

Azure 上取得服务单价资料方式只有一个 API : https://prices.azure.com/api/retail/prices,返回的资料结构 :

{
   "BillingCurrency":"USD",
   "CustomerEntityId":"Default",
   "CustomerEntityType":"Retail",
   "Items":[
      {
         "currencyCode":"USD",
         "tierMinimumUnits":0.0,
         "retailPrice":10.56,
         "unitPrice":10.56,
         "armRegionName":"uksouth",
         "location":"UK South",
         "effectiveStartDate":"2018-11-01T00:00:00Z",
         "meterId":"0001d427-82df-4d83-8ab2-b60768527e08",
         "meterName":"E10 Disks",
         "productId":"DZH318Z0BP88",
         "skuId":"DZH318Z0BP88/001V",
         "productName":"Standard SSD Managed Disks",
         "skuName":"E10 LRS",
         "serviceName":"Storage",
         "serviceId":"DZH317F1HKN0",
         "serviceFamily":"Storage",
         "unitOfMeasure":"1/Month",
         "type":"Consumption",
         "isPrimaryMeterRegion":true,
         "armSkuName":""
      }
   ],
   "NextPageLink":"https://prices.azure.com:443/api/retail/prices?$skip=100",
   "Count":100
}

因为 Azure 上服务太多了,资料量太大,所以此 API 每个请求只能返回 100 笔资料,并提供 NextPageLink 属性给下 100 笔资料的 URL

藉此笔者这边简单写一个 C# 下载脚本,如下
大约完整下载需要一段时间,所以提供抓完的资料 : 2020-10-12-AzurePrices.json (79MB,135101笔资料) 给读者参考。

void Main()
{
	var client = new HttpClient();
	var list = new List<Price>();
	var i = 0;
	while(true))
	{
		var url = $"https://prices.azure.com/api/retail/prices?$skip={i*100}";
		var content = client.GetStringAsync(url).Result;
		var data = JsonConvert.DeserializeObject<Retail>(content);
		
		// 如果没有下100资料,NextPageLink 会是 null,停止继续分析
		// e.g : {"BillingCurrency":"USD","CustomerEntityId":"Default","CustomerEntityType":"Retail","Items":[],"NextPageLink":null,"Count":0}
		if(data.NextPageLink == null)
			break;
		list.AddRange(data.Items);
		i++;
		Console.WriteLine(i);
	}
	
	//将结果保存到 
	var path = Path.Combine(GetDownloadFolderPath(),"AzurePrices.json");
	File.WriteAllText(path,JsonConvert.SerializeObject(list));
}

string GetDownloadFolderPath()
{
	return Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "{374DE290-123F-4565-9164-39C4925E467B}", String.Empty).ToString();
}

public class Price
{
	public string currencyCode { get; set; }
	public double tierMinimumUnits { get; set; }
	public double retailPrice { get; set; }
	public double unitPrice { get; set; }
	public string armRegionName { get; set; }
	public string location { get; set; }
	public DateTime effectiveStartDate { get; set; }
	public string meterId { get; set; }
	public string meterName { get; set; }
	public string productId { get; set; }
	public string skuId { get; set; }
	public string productName { get; set; }
	public string skuName { get; set; }
	public string serviceName { get; set; }
	public string serviceId { get; set; }
	public string serviceFamily { get; set; }
	public string unitOfMeasure { get; set; }
	public string type { get; set; }
	public bool isPrimaryMeterRegion { get; set; }
	public string armSkuName { get; set; }
	public string reservationTerm { get; set; }
}

public class Retail
{
	public string BillingCurrency { get; set; }
	public string CustomerEntityId { get; set; }
	public string CustomerEntityType { get; set; }
	public List<Price> Items { get; set; }
	public string NextPageLink { get; set; }
	public int Count { get; set; }
}

接着转成 csv 的脚本,这边有提供放在 Github 已转好档案 2020-10-12-AzurePrices.xlsx

image

void Main()
{
	var path = @"azure json Prices Json 路径";
	var json = File.ReadAllText(path);
	var dt = JsonConvert.DeserializeObject<DataTable>(json);
	dt.WriteToCsvFile(@"C:\Users\HanYang\Downloads\AzurePrices.csv");
}

public static class DataTableExtensions
{
	public static void WriteToCsvFile(this DataTable dataTable, string filePath)
	{
		StringBuilder fileContent = new StringBuilder();

		foreach (var col in dataTable.Columns)
		{
			fileContent.Append(col.ToString() + ",");
		}

		fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);

		foreach (DataRow dr in dataTable.Rows)
		{
			foreach (var column in dr.ItemArray)
			{
				fileContent.Append("\"" + column.ToString() + "\",");
			}

			fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
		}

		System.IO.File.WriteAllText(filePath, fileContent.ToString());
	}
}

接着就能做查询动作 :

想知道同样服务所有区域的价格从低到高

举例 : 想知道 app service 所有区域价格低到高
方式 : 转成 filter 模式 > 将 serviceName 筛选 Azure App Service > unitPrice 选择正序排序

image
image

想知道同样服务那些区域有支援

方式 : 在armRegionName filter 就可以看到那些地区有支援
image


<<:  关於 background 属性

>>:  【Day-26】我们是怎麽开始的?:一间传统软件公司从 0 开始建置的 DevOps 文化(工具篇)- 高品质工作四部法

Day1 写程序的前置工作!

安装环境第一步骤 App Store 搜寻Xcode并下载 下载後并创立一个专案 进入後系统帮我们预...

Day 16:axios 先封装,API 轻松发

上篇我们在单一元件内使用 axios 发送 API,但如果专案规模愈来愈大,需要同时管理多个功能的 ...

Annotation 的设计与想法

Annotation 要怎麽定义会影响使用这个 library 的使用者体验,annotation ...

Day24 [实作] 一对一视讯通话(4): 加入通话及挂断机制

结合前两篇我们已经实现了 MVP(Minimum Viable Product;最小可行产品),完成...

Day 13 - 基本语法8(函式2)

昨天我们学完了函式的基础用法以及讲解,今天要写的是进阶用法。 会这样分两天是因为我觉得有一点难,可以...