Python Streamlitでherokuにデプロイ 備忘録



herokuにchromeをインストールするためのビルドパックを追加

$ heroku buildpacks:add --index 1 https://github.com/heroku/heroku-buildpack-chrome-for-testing

Heroku Buildpacksの設定: Herokuにheroku-buildpack-aptを追加して、Aptパッケージをインストールできるようにします。これにより、カスタムAptパッケージを追加できるようになります。

heroku buildpacks:add --index 1 heroku-community/apt

Aptfileの作成: プロジェクトのルートディレクトリにAptfileを作成し、その中にgoogle-chrome-stableを記述します。

# Aptfile
https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

pythonでherokuのデータベース設定

$ heroku addons:create heroku-postgresql:mini      

デプロイしたらこんなエラーが出てきました。

Traceback:
File "/app/.heroku/python/lib/python3.12/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 600, in _run_script
    exec(code, module.__dict__)
File "/app/main.py", line 525, in <module>
    create_thread_controls(i, device_type)
File "/app/main.py", line 435, in create_thread_controls
    saved_settings = load_settings_from_db(index)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/main.py", line 50, in load_settings_from_db
    cursor.execute("SELECT * FROM settings WHERE index = %s", (index,))
File "/app/.heroku/python/lib/python3.12/site-packages/psycopg2/extras.py", line 236, in execute
    return super().execute(query, vars)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

どうやらsettingsがうまくいっていないらしいので作成します。
まずはデータベースに接続して、

$ heroku pg:psql --app your-heroku-app-name

SQLスクリプトを打ち込みます

CREATE TABLE settings (
    index SERIAL PRIMARY KEY,
    url TEXT,
    number INTEGER,
    start_time TIME,
    end_time TIME,
);

これでsettigsが作成されうまくいきました。

$ heroku config:set TOTAL_THREADS=40 --app your-heroku-app-name

herokuのタイムゾーンとローカルのタイムゾーンが違ったので沼りかけた件

import pytz

datetimeの値の受け渡しがstringでないとエラーが発生した。
herokuのタイムゾーンを設定

$ heroku config:add TZ=Asia/Tokyo
# 時間を文字列からtimeオブジェクトに変換
if isinstance(settings['開始時間'], str):
    settings['start_time'] = datetime.datetime.strptime(settings['start_time'], "%H:%M:%S").time()
if isinstance(settings['終了時間'], str):
  settings['end_time'] = datetime.datetime.strptime(settings['end_time'], "%H:%M:%S").time()

開始時間と終了時間を計算するとき

"""開始時間までの秒数を計算します。"""
now = datetime.datetime.now(pytz.utc)  # 現在のUTC時間を取得
local_tz = pytz.timezone('Asia/Tokyo')  # ローカルタイムゾーンを設定
local_start_time = local_tz.localize(datetime.datetime.combine(now.date(), self.start_time))  # ローカルタイムゾーンでの開始時間を設定
start_dt = local_start_time.astimezone(pytz.utc)  # 開始時間をUTCに変換