仕事やプライベートで調べたことのメモ書きなど(@札幌)

仕事やプライベートで調べたこと、興味ある事のメモ書きです。2016年4月から札幌で働いてます。※このブログは個人によるもので、団体を代表するものではありません。

Pythonのloggingでログが重複して困った話 [fbprophet]

Pythonでログが重複する話は比較的よくある模様。

自分で作ったLoggerでログが重複してしまったのであれば以下のようなものも参考になるが・・・。
uyamazak.hatenablog.com

今回はいろいろ調査した挙句、インポートして使っているライブラリであるfbprophetに原因があった。
github.com

このライブラリは以下のようにLoggerを初期化していたのです。
github.com

basicConfigを見てみると、、、Root Loggerが生成されます。
docs.python.org

自分でロガーを別途生成して制御していたのにもかかわらず、ライブラリで勝手にRoot Loggerを作るため、自分で作ったLoggerへのログ出力も重複してしまうことになったのです。。。
そういう時は、先回りしてLoggerを殺して(もしくは自分の仕様にあったLoggerを生成して)あげましょう。

Pythonのloggingか階層構造を持っているから、とも言えます。
qiita.com

ちなみに、fbprophetでは、内部的にpystanも使っており、pystanも同様のコードでLoggerを初期化してるので要注意。
Root Loggerが勝手に作られる処理を殺したければ以下のようなコードでどうぞ♪(この場合は、当然、fbprophetからログが出なくなるので、出力したい場合は適切なHandlerを設定してください。)

logging.getLogger('fbprophet').addHandler(logging.NullHandler())
logging.getLogger('pystan').addHandler(logging.NullHandler())

以上

C#でのAzure Functionsの呼び出しにはまった

Azure Functions(HttpTrigger)で何らかのFunctionsを追加すると、通常は、
https://xxxxxx.azurewebsites.net/api/xxxxx的なURLが作成されます。

で、以下のコードを書きました。

        WebClient wc = new WebClient();
        string url = "https://xxxxxx.azurewebsites.net/api/xxxxx";
        Stream st = wc.OpenRead(url);
        Encoding enc = Encoding.GetEncoding("utf-8");
        StreamReader sr = new StreamReader(st, enc);
        string html = sr.ReadToEnd();
        sr.Close();
        st.Close();
        Console.WriteLine(html);

そうると、、、、呼び出し時にエラーとなります。

>bin\Debug\ConsoleApplication1.exe

ハンドルされていない例外: System.Net.WebException: 接続が切断されました: 送信時に、予期しないエラーが発生しました。。 ---> System.IO.IOException: 転送接続からデータを読み取れません: 既存の接続はリモート ホストに強制的に切断されました。。 ---> System.Net.Sockets.SocketException: 既存の接続はリモート ホストに強制的に切断されました。
   場所 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
:
:

Functionsの何か書き方がまずいのかとか、、、半日くらいいろいろ試行錯誤しました。
一晩寝たところ、なんと https を http に変えたら動くんじゃないかという神のお告げが。。。。
そして見事動きました!

でも何か悶々としていて、数日後にググってみると、今のページへめぐり逢い。。。。

fullvirtue.com
ちなみにHttpClientでも同様なようです。
qiita.com

なんと、一行追加するだけで動きましたとさ。

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        WebClient wc = new WebClient();
        string url = "https://xxxxxx.azurewebsites.net/api/xxxxx";
        Stream st = wc.OpenRead(url);
        Encoding enc = Encoding.GetEncoding("utf-8");
        StreamReader sr = new StreamReader(st, enc);
        string html = sr.ReadToEnd();
        sr.Close();
        st.Close();
        Console.WriteLine(html);

めでたしめでたし。

PythonでAES暗号化/復号(PyCryptodomeにするときに必要な変更)

以下を参考に、Pythonでの暗号化復号化を実施。かつ、PyCryptodome の方がいいということで試してみました。

qiita.com

必要な変更は以下。

  • cipher.encrypt(raw.encode('utf-8'))
  • return self._unpad(cipher.decrypt(enc[16:]).decode())

後者のself._unpad追加は短いパスワードにも対応するときに必要だったこと。(たぶん)

Azure Functionsで環境変数を取り扱う(Python編)

Python上のコードとしては、通常の環境変数を取り扱うように書ける模様。
以下を参考に対応。
note.nkmk.me

そして以下を参考に、Azure Portal上で環境変数を設定します。
qiita.com

WSL上のdocker engineの試行錯誤

自分がやろうとしていることがdocker for windowsだとうまくいかそうだったので、WSL(ubuntu)上のdockerについて試しました。

qiita.com

上記を試すも、以下にハマり・・・。

teratail.com

で、docker.io でなく、docker-ceを使うべし、というのをどこかで発見したので、
そちらで試しにやってみたところ、そこについては突破したっぽい!!

また別の壁に今はぶつかっているところですが・・。

Azure FunctionsでPythonを使うメモ(LinuxイメージのFunction追加&pyodbc&fbprophet編)

(2019/1/23訂正)
LinuxイメージのAzure FunctionsへのFunction追加ですが、基本はバイナリ依存するようなモジュールはすんなり追加できません。
それでも、pyodbcだと「--build-native-deps --no-bundler」だけでいけたのですが、fbprophetに結構苦戦して、できたりできなかったりしていたのですが・・・。

結論:fbprophetのビルドには大量にメモリを使うので・・、docker for windows上でやるときはメモリをたくさん割り当てる必要がある

作業は、WSL(Ubuntu)+docker for windows(Windows 10 pro)で実行したのですが、docker for windowsで作業する場合、VMに割り当てるメモリを設定できます。1時期4GBにしたことがあったのですが、基本は2GBでやってました。が、これがいけなかった。
2GBだとビルドも時間がかかり、挙句の果てにはエラー。4GBは割り当てましょう!

ちなみにfbprophetは、Facebook社開発の予測ライブラリです。
facebook.github.io

xxxxxx$ python -m venv venv
xxxxxx$ source venv/bin/activate
(venv) xxxxxx$ func init
Select a worker runtime:
1. dotnet
2. node
3. python
Choose option: 3
python
Installing wheel package
Installing azure-functions==1.0.0a5 package
Installing azure-functions-worker==1.0.0a6 package
Running pip freeze
(venv) xxxxxx$ func --version
2.3.148
(venv) xxxxxx$ pip install pyodbc
(venv) xxxxxx$ pip install fbprophet
(venv) xxxxxx$ pip install scipy
(venv) xxxxxx$ pip install statsmodels
(venv) xxxxxx$ pip freeze > requirements.txt
(venv) xxxxxx$ vi requirements.txt (※「pkg-resources==0.0.0」を削除)
(venv) xxxxxx$ func host start (※ローカルでの稼働を確認)

                  %%%%%%
                 %%%%%%
            @   %%%%%%    @
          @@   %%%%%%      @@
       @@@    %%%%%%%%%%%    @@@
     @@      %%%%%%%%%%        @@
       @@         %%%%       @@
         @@      %%%       @@
           @@    %%      @@
                %%
                %

:
:
:

(venv) xxxxxx$ func azure functionapp publish MyXxxxxxFunc --build-native-deps --no-bundler
Getting site publishing info...
Running 'docker pull mcr.microsoft.com/azure-functions/python:2.0'...done
Running 'docker run --rm -d mcr.microsoft.com/azure-functions/python:2.0'....done

:
:
:

(venv) xxxxxx$

Azure FunctionsでPythonを使うメモ(LinuxイメージのFunction追加編)

前回、DockerImage編でうまくいきましたが、DockerImageだと従量課金を選べないので、なんとかFunctinを登録する方式を探していました。ただ、思わぬ苦戦。単純な関数でもうまくデプロイできずに困っていました。

ところが、以下の投稿を発見して解決。
github.com

「pkg-resources==0.0.0」という行が、pip freezeで追加されるバグがあるようです。この行をrequirement.txtから削除することでデプロイして実行できました!どうぞお試しください!