在树莓派上使用 PowerShell 调用 Azure 上的 .NET Core API 获取疫情数据

点击上方蓝字关注“汪宇杰博客”

导语

最近因为疫情被关在家里,做了个无聊成就:我们将在树莓派上用 PowerShell 调用 Azure 上的一个 .NET Core 写的 API 来获取疫情数据。

疫情数据API

疫情数据来源于腾讯新闻的一个实时更新的页面,原始 API 地址为:

https://view.inews.qq.com/g2/getOnsInfo?name=wuwei_ww_cn_day_counts"

然而我们没有办法直接使用,因为它的返回居然不是规范的 JSON:

因此,我只能自己 996 一下,用 .NET Core 包装了腾讯的 API,做了规范化的输出,最终结果为:

我们只需要将腾讯 API 中的 data 字符串取出,反序列化为强类型 model 即可。

public class InfectionData

{

    public DateTime Date { get; set; }

    public int Confirm { get; set; }

    public int Suspect { get; set; }

    public int Dead { get; set; }

    public int Heal { get; set; }

}

由于 System.Text.Json 福报非常多,我依旧使用老牌 Json.NET 搞定数据转换:

var data = await _httpClient.GetStringAsync(_settings.Value.DataSource);

var apiRes = JsonConvert.DeserializeObject<CoronavirusApiResponse>(data);

var infectionData = JsonConvert.DeserializeObject<IEnumerable<InfectionData>>(apiRes.Data);

代码地址:https://github.com/EdiWang/DotNet-Samples/tree/master/CoronavirusReport

其中用到的知识点为 HttpClient + Polly,这是 .NET Core 调用 REST API 最安全可靠的实践。

简单来说,就是为了调一个API,你得针对这个API建一个接口、一个实现,把 HttpClient 类型通过 services.AddHttpClient 加入 DI 传进来使用,最后利用 Polly 配置出错自动重试等异常处理。

public interface ICoronavirusApiClient

{

    Task<IEnumerable<InfectionData>> GetInfectionDataAsync();

}

public class CoronavirusApiClient : ICoronavirusApiClient

{

    private readonly HttpClient _httpClient;

    private readonly ILogger<CoronavirusApiClient> _logger;

    private readonly IOptions<AppSettings> _settings;

    public CoronavirusApiClient(

        HttpClient httpClient, 

        ILogger<CoronavirusApiClient> logger, 

        IOptions<AppSettings> settings)

    {

        _logger = logger;

        _settings = settings;

        _httpClient = httpClient;

    }

    public async Task<IEnumerable<InfectionData>> GetInfectionDataAsync()

    {

        var data = await _httpClient.GetStringAsync(_settings.Value.DataSource);

        var apiRes = JsonConvert.DeserializeObject<CoronavirusApiResponse>(data);

        var infectionData = JsonConvert.DeserializeObject<IEnumerable<InfectionData>>(apiRes.Data);

        var infectionDataArray = infectionData as InfectionData[] ?? infectionData.ToArray();

        _logger.LogInformation($"Got {infectionDataArray.Length} records from '{_settings.Value.DataSource}'");

        return infectionDataArray;

    }

}

services.AddHttpClient<ICoronavirusApiClient, CoronavirusApiClient>()

        .AddTransientHttpErrorPolicy(builder =>

        builder.WaitAndRetryAsync(3, retryCount =>

                TimeSpan.FromSeconds(Math.Pow(2, retryCount)),

            (result, span, retryCount, context) =>

            {

                _logger?.LogWarning($"Request failed with {result.Result.StatusCode}. Waiting {span} before next retry. Retry attempt {retryCount}/3.");

            }));

至于为什么不能简单粗暴 new 一个 HttpClient 直接调API,推荐观看另一名 MVP Steve Gordon 的视频《Let's Talk HTTP in .NET Core》:https://www.youtube.com/watch?v=ojDxK_-I-To   (咦,这是什么不存在的网站)

最后,我把处理好格式的的疫情 API 部署到了Azure国际版的 App Service 上。

https://covid19cn.azurewebsites.net/infectiondata

Linux居然有PowerShell?

由于 Windows 10 早已是一盘咖喱拌饭,导致在树莓派上最好用的系统只能是 Linux,而我这种微软系程序员显然不熟悉 bash,如果能用上 PowerShell 那就太好了!随着微软的开源、开放(Linux First, Windows Last)的态度,PowerShell 其实也和 .NET 一样,已经能够跨平台运行。

以树莓派官方系统 Raspbian 为例,安装 PowerShell 的方式如下:

sudo apt-get install libunwind8

wget https://github.com/PowerShell/PowerShell/releases/download/v7.0.0-rc.3/powershell-7.0.0-rc.3-linux-arm32.tar.gz

mkdir ~/powershell
tar -xvf ./powershell-7.0.0-rc.3-linux-arm32.tar.gz -C ~/powershell
sudo ln -s ~/powershell/pwsh /usr/bin/pwsh
sudo ln -s ~/powershell/pwsh /usr/local/bin/powershell
powershell

PowerShell 的最新发布可以关注官方 GitHub:https://github.com/PowerShell/PowerShell/releases

参考:https://www.hanselman.com/blog/InstallingPowerShellCoreOnARaspberryPiPoweredByNETCore.aspx

另外,如果你和我一样用树莓派4,那么 Ubuntu 19.10.1 作为64位系统,可以通过相同方法安装64位 PowerShell,感兴趣的可以尝试。

现在我们可以愉快的调用疫情数据了!PowerShell 自带一个 Invoke-RestMethod 方法专门用来调用 REST API,非常方便,996。而 Format-Table 则可以把返回的 JSON 对象直接用表格形式来展示,更不会 996!

Invoke-RestMethod 参考:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7

当然,你在 Windows 咖喱味 PC 上也能用经典 PowerShell 做这件事:

v7.0.0-preview.4 - 09/19/2019 Engine Updates and Fixes Add support to ActionPreference.Break to break into debugger when Debug, Error, Information, Progress, Verbose or Warning messages are generated (#8205) (Thanks @KirkMunro!) Enable starting control panel add-ins within PowerShell Core without specifying .CPL extension. (#9828) Performance Make ForEach-Object faster for its commonly used scenarios (#10454) and fix ForEach-Object -Parallel performance problem with many runspaces (#10455) Experimental Features Update PSDesiredStateConfiguration module version to 2.0.3 and bring new tests; enable compilation to MOF on non-Windows and use of Invoke-DSCResource without LCM (#10516) Add APIs for breakpoint management in runspaces and enable attach to process without BreakAll for PowerShell Editor Services (#10338) (Thanks @KirkMunro!) Support ternary operator in PowerShell language (#10367) General Cmdlet Updates and Fixes Add PowerShell Core group policy definitions (#10468) Update console host to support XTPUSHSGR/XTPOPSGR VT control sequences that are used in composability scenarios. (#10208) Add WorkingDirectory parameter to Start-Job (#10324) (Thanks @davinci26!) Remove the event handler that was causing breakpoint changes to be erroneously replicated to the host runspace debugger (#10503) (Thanks @KirkMunro!) Replace api-ms-win-core-job-12-1-0.dll with Kernell32.dll in Microsoft.PowerShell.Commands.NativeMethods P/Invoke API(#10417) (Thanks @iSazonov!) Fix wrong output for New-Service in variable assignment and -OutVariable (#10444) (Thanks @kvprasoon!) Fix global tool issues around exit code, command line parameters and path with spaces (#10461) Fix recursion into OneDrive - change FindFirstFileEx() to use SafeFindHandle type (#10405) Skip auto-loading PSReadLine on Windows if the NVDA screen reader is active (#10385) Increase built-with-PowerShell module versions to 7.0.0.0 (#10356) Add throwing an error in Add-Type if a type with the same name already exists (#9609) (Thanks @iSazonov!)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值