1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FastAPI(Python3)でサーバを立ててMaya2020以前(Python2.7)からリクエストする

Posted at

はじめに

簡単にサーバが立てられちゃうFastAPIというライブラリを使って、Maya2020(Python2.7)からアクセスしてみました。

  • メリット
    • サーバ側はPython3で作るので Python3系のパッケージを扱える。
    • 何も追加インストールしていない 素のMaya2020以前(Python2.7) でOK。
    • そもそもMayaの外側で動かすので MayaのPythonバージョンに縛られない。
  • デメリット
    • 出来ることが限られる。Mayaに直接触れるようなものは書けない。(maya.cmds, UI関係など)
    • 必要な処理を事前に切り離して用意しておかないといけない。
    • サーバアプリを起動しておかなければならない。(Maya起動と連動させられれば特に気にならないかも)

テスト環境

  • Windows 10
  • Maya 2020 (Python 2.7.11)
  • Python 3.10.9

サーバアプリを作る

まずFastAPIが使えるPython3.6以降の環境でfastapiuvicornをインストールします。
ここはまだMayaではなくVSCodeとかでやります。

// 仮想環境の作成
python -m venv venv
venv\Scripts\activate
python -m pip install -U pip

// パッケージインストール
pip install fastapi uvicorn

次にサーバを作成します。

main.py
import os
from fastapi import FastAPI
from pydantic import BaseModel

import openai # ※これはサーバとは直接関係ないです

# APIリクエストに含まれるデータの構造と型を定義
class RequestData(BaseModel):
    model: str
    messages: list
    temperature: float = 1.0
    top_p: float = 1.0
    presence_penalty: float = 0.0
    frequency_penalty: float = 0.0

# FastAPIアプリケーションインスタンスを作成
app = FastAPI()

# POSTリクエストを受け付けるAPIエンドポイントを定義
@app.post("/openai/")
async def chat_completion(request_data: RequestData):
    """
    何らかのやりたい処理を書きます
    """

    # ※以下の例はOpenAI APIへリクエスト作成しレスポンスを取得するもの(別途 pip install openai してます)
    dict = request_data.dict()
    response = openai.ChatCompletion.create(
        model=dict["model"],
        temperature=dict.get("temperature", 1.0), 
        top_p=dict.get("top_p", 1.0), 
        presence_penalty=dict.get("presence_penalty", 0.0), 
        frequency_penalty=dict.get("frequency_penalty", 0.0), 
        messages=dict["messages"]
    )
    return response

コマンドラインで以下を入力しサーバを起動します。

uvicorn main:app --reload

こんな感じになれば成功です。Ctrl+Cで終了させられます。
image.png

ちなみに、このくらいであればPyInstallerでexe化した1ファイルだけを別のPythonが入っていないPCに置いても正常に動作しました。

main.pyuvicornが含まれるよう以下を書き加えます。
引数を追加していますが重要なのは最後のuvicorn.run()です。

main.py (exe用 追記分)
import argparse
import uvicorn
import socket

"""(中略)"""

# コマンドライン引数のパーサー作成
parser = argparse.ArgumentParser()

# ローカルIPを取得するオプション追加
parser.add_argument(
    "-l", "--get_local_ip",
    action="store_true", 
    default=False,
)

# ポート番号を指定するオプション追加
parser.add_argument(
    "-p", "--port",
    type=int,
    default=8000,
)

opt = parser.parse_args()

# --get_local_ipが指定された場合はローカルIP取得、指定が無ければデフォルトの127.0.0.1
if opt.get_local_ip:
    hostname = socket.gethostname()
    host = socket.gethostbyname(hostname)
else:
    host = "127.0.0.1"

# 実行
uvicorn.run(app, host=host, port=opt.port)

pyinstallerでexe化します。

pip install pyinstaller
pyinstaller main.py --onefile

distフォルダにmain.exeが出来ていますのでダブルクリックで起動します。
LAN内にある別のPCに配置する場合は-lオプションをつけて起動します。

main -l

Maya2020からリクエストする

ようやくMayaさんの登場です。MayaはAPIリクエストのみを行います。
Maya2020にはrequestsが入っていないので、urllib2を使っています。

Maya 2020 ScriptEditor
import urllib2
import json

# リクエストデータ
data = {
    'model': 'gpt-3.5-turbo',
    'messages': [
        {'role':'system', 'content':u'語尾に「にゃ」を付けて答えてください。'},
        {'role':'user', 'content':u'日本の代表的な観光地を5つ教えて。'}
    ]
}

# リクエスト
req = urllib2.Request(
    'http://127.0.0.1:8000/openai/',
    headers={'Content-Type': 'application/json'},
    data=json.dumps(data)
)
response = urllib2.urlopen(req).read()

# 結果出力
response = json.loads(response)
print(response['choices'][0]['message'].get('content'))
結果
東京タワー京都の清水寺富士山広島の原爆ドーム沖縄の首里城にゃ

他に例を挙げたくて、Mayaの外部に切り離したいものって何かあるかな~と考えてみたのですが...

特に思いつきませんでした...w 活用例お待ちしてます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?