A certain engineer "COMPLEX"

.NETでPythonを試してみる 第5回

前回はIronPythonを捨てて、RESTを使ってPythonと連携しました。

Introduction


C#からPythonで公開したREST APIを呼び出すことには成功しました。
逆にC#で公開したREST APIを呼び出すことも可能です。
定期的にPython側での処理結果をC#側にプッシュするような形態のシステムもあり得ますので、PythonからC#への通信方法を知ることも有用でしょう。

今回のソースは下記になります

Sample source code for Demonstration, Experiment and Test - takuya-takeuchi/Demo

Python


requestsインストール

requestsは「人間のためのHTTP」と銘打った、極めてシンプルで洗練されたHTTPライブラリです。

インストールもお馴染みのpipで簡単。

以上でインストールは完了です。

ソース

前回のソースに手を加えた感じです。

getメソッド内で、DateTimeServiceClient._sendメソッドを呼び出します。
_sendメソッドは、外部のREST APIに対してPOSTで現在時刻を渡します。
つまり、外部(C#)から自身のREST APIを呼ばれている最中に、外部(C#)のREST APIを呼び出します。

重要なことですが、

  • headerspostメソッドに渡してください
  • paramsdateTimeキーの文字列を間違えないでください
  • postメソッドの第一引数はC#側ときちんと一致させること

これらが守られないと、クラッシュしたり、正しく動きません。
Python側は以上です。

C#


インストールするライブラリは前回と同じです。

ソース

WPFです。Xaml側は省略します。
Xamlは、Python側のREST APIを呼び出すButton、Python側から受け取る現在時刻情報を追加するListBoxです。
ViewModelもButtonに対応するコマンドと現在時刻のコレクションだけです。

まずは、公開するREST APIです。

肝はSendメソッドに付与されたWebInvoke属性です。
プロパティは重要ですが、UriTemplateプロパティの値は特に重要です。
Sendメソッドの名前と、UriTemplateプロパティのSendは一致させる必要はありませんが、UriTemplateプロパティのSendはPython側で、postメソッドで指定した値と一致させます。
同様に、dateTimeもPython側のparamsのキーと一致させます。
ちなみに、UriTemplateプロパティのparamDateTimeの部分は、Sendメソッドの引数、paramDateTimeと一致させないと、アプリ起動時にクラッシュします。
Sendメソッドの中身は単純で、渡ってきた文字列をDateTime型に変換し、イベントを呼び出すだけです。

次にViewModelです。

MessageCommandがPython側のREST APIを呼び出します。
また、その呼び出しで、C#側のREST APIがPython側から実行され、Python側から渡ってきた時刻がResponsesコレクションに追加されます。

最後にViewModelLocatorです。

WebServiceHostインスタンス生成時のUrlに注意するのと、IDateTimeServiceに対応する実際の型は、MinaViewModelに保持するインスタンスと、WebServiceHostで保持するインスタンスは同一であることに注意します。
ポート番号も一致させます。
C#は以上です。

テスト


実際に実行してみます。
C#側を起動する前に、PythonでRESTサービス側を起動しておいてください。
ボタンを押下すると、Python側から受け取った現在時刻が画面下部のListBoxに追加されていきます。

Conclusion


C#側のRESTを活用して、C#とPythonで双方向通信が可能になりました。
実はRESTを使用したアプリを作るのは初めてでした。
WebInvoke属性の値の設定で苦労しましたが、良い経験になりました。

Source Code

https://github.com/takuya-takeuchi/Demo/tree/master/WPF.Python5

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。