銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Microsoft Fabricをお試しするには (Microsoft AI Tour Tokyoに参加してきました)

昨日、Microsoft AI Tour Tokyoに参加してきました。その中で、Microsoft MVPとして「Microsoft Fabric でデータサイエンスを始めよう」というワークショップのお手伝いをしてきました。

envision.microsoft.com

お手伝いのために自分でもMicrosoft Fabricをいろいろ試していたのですが、どうお試しできるのかというのを簡単に紹介したいと思います。ワークショップ参加した方には、Fabricが使えるのであれば家に帰ってからも使えますというリンクが紹介されていたと思いますが、その使えるようになるための方法です。

もちろん購入すれば使えます。価格のページはこちらです。

azure.microsoft.com

お試しするのに購入はちょっとという場合は無料試用版が使えます。

learn.microsoft.com

試用は60日間となりますが、すべてのFabricのエクスペリエンスと機能へのフル アクセスに加えて、OneLakeストレージを最大1 TBまで取得でき、64容量ユニット(CU)まで使えます。試用にはPowerBIが利用できることが必要ですが、PowerBI自体も評価版を利用できます。 ただ、テナントを持つ組織アカウントが必要なので、会社のテナントだと気軽に使えないかもしれません。そんな場合はMicrosoft365の試用版を経由して利用する方法も上のドキュメントには紹介されています。M365の試用->PowerBIの試用->Fabricの試用、という三段構えになっています。

さてここからが一番紹介したいことです。いざ試用版が使えるようになっても、なにをどう動かせばFabricが使えるかわからないかもしれません。そういう場合はMicrosoft Learnがあります。Fabric関連のモジュールは以下のリンクで一覧が見れます。

learn.microsoft.com

モジュールの中には演習として実際にFabricを操作するユニットがあります。Microsoft LearnのAzureの演習だとLab用のAzure環境がブラウザ内でそのまま利用できたりしますが、Fabricの場合は自分が持ってるFabricアカウントを使って動かす前提になっています。ですので、せっかくFabricの試用版を有効にしたら、使えるうちにこれらのモジュールをコンプリートすることをおすすめします。

Radiusを知る(11) v0.30のリリースと最近の機能追加

Radius v0.30 がリリースされました。

github.com

Terraformレシピの強化

サブモジュールのサポート、Git モジュール ソースのサポート、バージョン範囲など、Terraform レシピにサポートされる新しい機能とシナリオが多数追加されました。private moduleは未対応ですが、public moduleがサポート対象となっています。

docs.radapp.io

Radiusダッシュボード

実験的機能ですが、GUIから Radius 環境、アプリケーション、レシピを操作できるようになりました。

github.com

プレゼン用資料

Radiusの機能とは関係ないですが、Radiusに関するプレゼンを作成するときに役立つアイコンやポンチ絵集、過去のスライド集が公開されています。

docs.radapp.io

OpenFeature .NET SDKを試してみた(3) データ型と評価API

OpenFeature .NET は1/23にv1.4.1がリリースされました。

github.com

今回からこのバージョンで検証したコードを書いていますが、(1),(2)で扱った範囲では SetProviderメソッドが非推奨となり、代わりに非同期なSetProviderAsyncメソッドが導入されました。

var flagdProvider1 = new FlagdProvider(new Uri("http://localhost:8013"));
await Api.Instance.SetProviderAsync(flagdProvider1);

ではOpenFeatureがサポートしているデータ型と評価APIを試してみます。

データ型

OpenFeatureがサポートしているデータ型は以下の5つです。

  • ブール
  • 文字列 (UTF-8エンコード)
  • 数値 (整数、浮動小数点など実装言語により、さらに詳細な型や機能が提供されることがある)
  • 構造型データ(実装言語の慣例でJSONやYAMLなどが使われる)
  • 日付(オプションでタイムゾーン付き、ない場合はUTCとして扱う)

openfeature.dev

評価API

OpenFeature .NETのAPIでは

  • ブールは GetBooleanValue
  • 文字列は GetStringValue
  • 数値は整数型(int)が GetIntegerValue 、浮動小数点型(double)が GetDoubleValue
  • 構造データが GetObjectValue

となっており、日付型に対応したAPIがありません。ただ、ほかの言語のSDKを見ても日付型に対応したAPIの実装が確認できなかったので、.NET 特有の問題ではないようです。仕様のドキュメントにもデータ型への対応については詳細がなく今のところ理由がわかりませんでした。

OpenFeature .NET の評価APIは上に挙げたような命名規則ですが、すべて非同期(async)メソッドになっているので返り値の型はTaskです。他の多くの .NET ライブラリと異なり、XxxAsyncという命名になっていませんが、これは 2.0.0 で変更される方針で議論が進んでいるようです。

github.com

また、ほかのAPIはGetXxxAsyncのXxxがデータ型名を表していますが、構造データを返す GetObjectValue だけはobject(Task)ではなくて、OpenFeature.Model.Value というSDKで定義された型となっています。Value型はOpenFeatureのオブジェクトを扱うためのクラスですが、IsXXXプロパティで中に入っているデータが該当の型であるかどうか判別するAPIと、AsXXXプロパティで中に入っているデータを該当の型で取得するAPIが用意されています。そのため、あらかじめデータ構造がわかっていればAsXXXプロパティでデータを取得できますが、そうでない場合はかなり面倒な処理が必要になります。

一例としてこのようなオブジェクトをflagdに与えているとします。

{
  "flags": {
    "myObjectFlag1": {
      "state": "ENABLED",
      "defaultVariant": "foo",
      "variants": {
        "foo": {
          "foo1": "foo1",
          "foo2": 1,
          "foo3": 1.5,
          "foo4": true
        },
        "bar": {
          "bar1": "bar1",
          "bar2": "bar2"
        }
      },
      "targeting": {}
    },
    "myObjectFlag2": {
      "state": "ENABLED",
      "defaultVariant": "foo",
      "variants": {
        "foo": {
          "foo": ["foo1", "foo2"]
        },
        "bar": {
          "bar": ["bar1", "bar2"]
        }
      },
      "targeting": {}
    }
  }
}

それぞれのフラグを取得する場合のコード例はこうなります。

var val3 = await client.GetObjectValue("myObjectFlag1", null);
dump(val3);
var val4 = await client.GetObjectValue("myObjectFlag2", null);
dump(val4);

static void dump(Value value)
{
    foreach (var (k, p) in value.AsStructure)
    {
        if (p.IsString)
        {
            Console.WriteLine($"{k} (string): {p.AsString}");
        }
        else if (p.IsNumber)
        {
            Console.WriteLine($"{k} (number): {p.AsDouble}");
        }
        else if (p.IsBoolean)
        {
            Console.WriteLine($"{k} (bool): {p.AsBoolean}");
        }
        else if (p.IsList)
        {
            Console.Write($"{k} (list): ");
            foreach (var v in p.AsList)
            {
                Console.Write(v.AsString );
            }
        }
    }
}

構造データを取得する場合、Value型の中身がValueのマップ構造データを表すOpenFeature.Model.Structure型になっています。そのため、まずAsStructureプロパティで取り出します。StructureはIEnumerable<KeyValuePair<string, Value>>を実装しているので、そのあとは上のようにデータ取得することになります。

詳細な評価API

まだブログで取り上げていませんが、OpenFeatureには与えたコンテキストに応じて動的な評価を行うなどさまざまな機能があります。そのような機能を使う場合、評価された値がなぜその値になっているか理由を知りたいことが出てきます。例えば、評価された値がデフォルト値である場合、動的な評価の過程で該当するものがないためデフォルトになったのか、該当するものがあってその評価の結果がデフォルト値と同じ値だったのか確認したいことがあります。そのような、メタデータと呼ばれる値を評価値とあわせて取得するためのAPIがOpenFeatureでは仕様として用意されています。

OpenFeature .NETの場合はGetXXXDetails という命名で、値だけを取得する評価APIと同じように用意されています。使い方は以下のようになります。

var details1 = await client.GetStringDetails("myStringFlag", "def");
Console.WriteLine(details1.FlagKey);
Console.WriteLine(details1.Variant);
Console.WriteLine(details1.Value);
Console.WriteLine(details1.Reason);
if (details1.ErrorType != ErrorType.None)
{
    Console.WriteLine(details1.ErrorType);
    Console.WriteLine(details1.ErrorMessage);
}
else
{
    Console.WriteLine("No error");
}

ReasonとErrorTypeの値の一覧は以下の仕様に記載されています。

openfeature.dev