[Python] PythonでSHOTGUNにアクセスする (1)

前回に続いてSHOTGUNネタ。


SHOTGUNにアクセスするにはPythonのAPI(shotgun_api3)を使用します。

が。が。。。。
このクラス、凄く使いにくいです。
多くの場合、プロジェクト単位で処理することが多いはずですが
sg.find(“Task”,filters=[XXX])
このようにアクセスしたら、全部とってきてしまうので、
毎度 {‘type’:’Project’,’id:XXX} を入れなきゃいけなかったり
カスタムエンティティの指定も CustomEntityXX とするので、何が何だか分からない。
fieldsも都度していなので面倒くさい.超面倒くさい。
そんなこんなでストレスマックスなので、それをカバーするClassを準備します。

まず、最終的にどうなってたら良いか自分なりに考えました。

希望はこんな感じ。

・プロジェクトは、IDではなく名前で指定したい。
・最初に指定したら、あとはそのプロジェクトのオブジェクトのみにしたい。
・1つのEntityにつき1つのClassとして扱えるようにしたい。
・Obj.EntityName.get() とかで、欲しいデータをオブジェクトで取得したい。
・取得するフィールドは指定したら全部とってくる。

大きくはこの5つ。
コレがかなうように下ごしらえをしていきます。

まず、カスタムエンティティの名前について。
自分で追加したエンティティは、CustomEntityXXの形でアクセスします。
が、、、、どれがどれなのか覚えていられません。
ので、対応する中身とEntityをDict型で定義します。

こんな感じ。
アクセスするときは find(CUSTOM_ENTITY[‘Art’])のようにすれば
コード的にはとてもわかりやすくなります。

続いて、Shotgunのメインのクラスを作成します。
メインのクラスではログインの管理をしたり、各エンティティのオブジェクトを作成したり
を出来るようにします。

必要最低限がこんな感じです。
引数でapi_nameやkey、プロジェクト名を指定し
ログインをします。
ログインチェックしてErrorの場合はraiseします。

コレを作った段階で分からなかったのが

sgObj = Shotgun(XXXX)
sgObj.Task.get()

こういう構造を作りたい場合は、どうしたら良いのか ということ。
Pythonの場合、クラスの関数や変数はどうなってるかというと
__dict__[func_name] この中で管理されています。
なので、別途

こんな感じで、各エンティティの管理クラスを配列に入れておき

こんな感じで初期化すればいけるんじゃないか?
ということになりまして、今回の形式になりました。
引数に入れるときに Task() ではなく Task とすると、Classそのものになるので
ENTITY_CLASS[0](sg,proj)
これと
Task(sg,proj)
は同じ意味となります。
このやり方でいいんでしょうかね(汗

次にプロジェクトについて。
プロジェクトも、「Project」という名前のEntityですが
これだけは割と扱いが特殊なので、別のクラス扱いにします。

こんな感じ。
アクセスするときはIDなので、初回時にIDを取得してくるようにします。
あと、filtersというのは、この後各Entityのクラスを作る時に
get() するときに使用するものになります。

で。
各EntityごとにSHOTGUNにアクセスできるようにしたいので
アクセス用のsgオブジェクトと、Project情報のProjectオブジェクトを渡しておきます。

次に各エンティティのクラスを作成します。
構造的には

1 共通
2 タスクの有無
3 固有のフィールド

この3段階になっているので、クラスも

親:
Base(共通)

子:
TaskEntity
Entity

こんな感じで定義しておいて、各Entityはタスクの有無で指定のクラスを継承すればOKにしておきます。

Baseには、get、update、delete、のような共通事項。
あとは、取得したいフィールドをとってくる等のような
共通で使用するプロパティを作成します。

TaskEntityには
get_task()
のように、Taskがある場合の固有の関数をつけるかたちしました。

Baseと各Entityの基本はこんな感じです。

まず、各エンティティごとに取得したいフィールドは
クラスの変数として定義しておきます。
この場合、全共通は _base_field、各Entityごとのフィールドは _field と
別にしておいて、
field プロパティで取得できるようにします。
つづいて、各Entityのキーになる名前(name,code,content)がどれかを指定します。
イマイチこのルールが分かってないのですが、なんとなーく
プロジェクトをまたいでるもの(Project,Tag)はname
各Entityはcode
Taskはcontent
という感じかなぁとおもってますが、時々エラー食らうのでよく分かりません(汗
ので、各Entityのクラスで指定しておきます。

最後に、 find(XXXX) で指定する、Entity名を指定します。

あとは、getのところで、SHOTGUN APIのfind()を使用して実際にタスクを取得し、
自分自身のClassオブジェクトを返すようにします。
get内で、findするときのフィルダーにProjectのIDをぶち込むようにします。
このとき、Tagのようにプロジェクトに関係なくアクセスするものもあるので
クラスには _is_proj という変数を定義しておき
プロジェクトに関係ない者はFalseを入れれば
フィルターにプロジェクトを入れないでも大丈夫にできます。

一応基本はこんな感じで
あとは使うEntity分を追加しつつ
Baseクラスに deleteやupdateなどのクラスを追加。
あとは、IDで取得することが多いので get_from_idや
複数IDを取得できる get_from_idsなんかを増やしたりしていきます。
その他には、チェックデータをアップすると upload_check_data()とか?

都度増やすのは面倒と言えば面倒なのですが、
こんな感じで一旦ラップしてあげることで、日常的なShotgunスクリプト(Daemonとか)
の作業スピードは格段に向上しました。

普段クラスを使って作る事のほうが希な自分なので、
このクラスの使い方正しいのか・・・?というのはありますが
もし、そうじゃねぇよ!!こうだよ!!
とかありましたら、指摘してもらえるとうれしいです。

あと、↑のコマンドはちゃんと試してないのでエラーにナル可能性もありますが
なんとなーくの雰囲気で捉えていただければ….orz

こんな感じで、アクセス周りの基本構造でした。
次回はこれに+して、Filter周りとかの追加とかをまとめようと思います。

コメントを残す

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

*