【Python】setuptoolsで自作モジュールを一発入魂

下記リポジトリのREADMEにソースと一緒にまとめた。

github.com

下記README

Python】setuptoolsで自作モジュールを一発入魂

  • setuptoolsを使ってsetup.pyを試してみたリポジトリです
  • できるだけ簡素な状態のリポジトリでパッと見てサクッと使えるように作りました
  • pipを使ってgitから一発インストールできます
pip install git+https://github.com/keix1/setuppy.git

setuptoolsについて

  • 今までは頑張ってsys.path.append()で自作モジュールをimportしていたが、相対パスを考えたりしなくてはならず面倒だった
  • setuptoolsなら自作モジュールをpipや開発環境に一発入魂できる
    • どこからでもimportできる
  • GitHubからもpip installできる
  • コマンドラインツールもinstallできる
  • twineを使えばPyPIにアップロードして普通にpip installもできるようになる

本レポのディレクトリ構造

.
├── setup.py
├── sample
│   ├── __init__.py
│   ├── hoge.py
│   └── sample.py
└── test
    └── test.py

Local develop

  • ローカルファイルを更新すると即座に更新が反映される。
  • 開発用途ならこれで良さそう。

Install on Local develop

インストール

cd setuppy
python setup.py develop

確認

pip list | grep sampleA

実行

python test/test.py

developインストールするなら下記は省いても動いた

  • __init__.py
  • setup.pyのpackagesとentry_points部分

Uninstall on Local develop

python setup.py develop -u

pip

  • GitHubに置けばGitHubから配布が可能になる
  • 当然だがスクリプトを更新したら再度pip installする必要がある
  • 上記で触れた__init__.pysetup.pyのpackage記述がいる

pip install

cd setuppy
pip install .

pip install from GitHub

pip install git+https://github.com/keix1/setuppy.git

pip uninstall

pip uninstall SampleA

コマンドラインツールとして使う

  • 本レポをInstall済みであればsample_commandが使えるようになっている
sample_command
  • setup.pyentry_pointsconsole_scriptsCLIツール指定するための記述になっている

わかったこと

  • develop installでは.egg-infoに関係性が保存されてる様子
  • __init__.pyは空ファイルでもいいみたい
  • CLIツールとして使えるのちょっとやばい

参考

WebRTCで撮影した動画をFastAPIにPOSTでファイルアップロードするときハマったこと

TL;DR 解決

下記でファイルアップロードできます。

Javascript側(送る側)

var f = new FormData();
var filename = "something.webm"
f.append("video", buffer, filename); // <=ここではまった
let xhr = new XMLHttpRequest();
xhr.open('POST', window.location.origin + '/uploadVideo', true);
xhr.send(f);

ちなみにbufferはblobです。

FastAPI側(受け取る側)

@app.post("/uploadVideo")
async def uploadVideo(video: UploadFile = File(...)): # <=ここではまった
    video_data = await video.read()
    upload_path = pathlib.Path(f'static/received_videos/{video.filename}')
    with upload_path.open(mode="wb") as f:
        f.write(video_data)
    return {"filename": video.filename}

ハマったところ2点

  • 必要なライブラリ
  • FastAPIの引数名

必要なライブラリ

下記が必要そう

pip install python-multipart

参考:Uploading images in FastAPI post request causes 400 Bad Request - Stackoverflow

FastAPIの引数名

async def uploadVideo(video: UploadFile = File(...)):

ここでvideoとなっているところは多くの記事でfileとかになっています。

FastAPIのPOSTで受け取る際はその引数の名前を送る側と同じにすることで受け取れるようになっているようです。

Javascriptを見るとたしかにvideoと指定して送ってますね。(無駄に自分で変えてた。。。)

実はFlaskでやって一回成功していたのですが、それがこちら。

from flask import request

@app.route('/uploadVideo', methods=["POST"])
def uploadVideo():
    received = request.files
    videofile = received['video']
    videofile.save('static/received_videos/' + videofile.filename)
    return str(received), 200

videoと指定して受け取っていますね。

教訓

割とどうでもいいようなところで結構な時間を使ってしまいました。

FastAPI初めてだったのでどこが違うか色々変な方向に疑って結果回り道してました。

今後はひとつひとつ成功したところを確認すること。

時々見かける便利そうなやつ:collections.Counter

collectionsとは?

このモジュールは、汎用の Python 組み込みコンテナ dict, list, set, および tuple に代わる、特殊なコンテナデータ型を実装しています。

  • namedtuple()
  • deque
  • Counter←今日はこれ
  • OrderedDict
  • defaultdict
  • UserDict
  • UserList
  • UserString

下記に記録した

Google Colab GitHub

まとめ

  • 頻度ランキング1位ゲットできるCounter.most_common()[0][0]は覚えておいてソンはないかも

FlaskオレオレHTTPS化

とりあえずブラウザでカメラ使いたいときなどに

参考:

qiita.com

気をつけたいポイント:

  • https://<アドレス>でアクセスする
  • EC2セキュリティグループで443を許可
  • server側portも443にする
  • 途中の要設定事項はこちら

sa1g.blogspot.com