StaSh の SSH を動かす方法 Pythonista 3 (ver. 3.4)

Pythonista 3.4 の StaSh で ssh を動かせたので、やったことをまとめます。

おことわり

Pythonista 3 のシェル環境 StaSh で ssh を使用するメリットについては触れません。ssh 接続をしている間は iPhone 本体が通常より熱を持つため、特にその必要が無い限り Termius 等の無料の SSH クライアント専用アプリを使用するのが良いと思います。本記事はむしろ、以前のバージョンの Pythonista 3 と StaSh で動いていたコマンドを、ver. 3.4 で動かす時の参考にしてもらえればと思います。また、再検証はしておらず、残しておいたメモを元に構成しているため、漏れや間違いがある可能性も否めません。

Pythonista 3.4 では、Python 2.7 のコードをそのまま実行することができなくなりました。StaSh に含まれるコマンドは全てが Python 3 に対応しているわけでは無く、ssh コマンド (ssh.py) もその一つです。以前の Pythonista (ver. 3.3 以前) では StaSh 自体を Python 2 環境で実行すれば ssh が実行可能でしたが、今後は Python 2 用コードは Python 3 に変換してあげる必要があります。Pythonista ではツールが用意されていて、スパナアイコンから Python 2 to 3 をタップすると自動変換してくれます。ただ、ssh コマンドは手直しが必要でした。

Python 2 のコードを開いた状態で Python 2 to 3 をタップすると変換してくれる

バージョン情報等

$ version
StaSh v0.8.0
Python 3.10.4 (CPython)
UI stash.system.shui.pythonista_ui
root: ~/Documents/site-packages/stash
core.py: 2023-05-05 18:00:40
SELFUPDATE_TARGET: master
Pythonista 3.4 (340012)
iOS 16.4.1 (64-bit iPhone10,2)
Platform iOS-16.4.1-iPhone10,2-64bit
BIN_PATH:
  ~/Documents/bin
  ~/Documents/stash_extensions/bin
  ~/Documents/site-packages/stash/bin

StaSh は、記事作成時に最新の dev バージョンです (StaSh インストール方法は別記事参照)

やったことひとまとめ

つど必要に応じて (変更箇所を反映させる等) Pythonista の再起動を実施しています。秘密鍵を使用した SSH の設定と、接続時の行数の指定例は過去記事をご参照下さい

  1. ~/Documents/site-packages/stash/bin/ssh.py を ~/Documents/stash_extensions/bin/ssh3.py としてコピー
  2. ssh3.py に対して「Python 2 to 3」を実行 (変更内容はそのまま)
  3. ssh3.py の関数 vk_tapped の内部 vk.name を全て int として処理するように書き換え (変更内容は下記)
  4. ~/Documents/site-packages/stash/system/shscreens.py に対して「Python 2 to 3」を実行 (変更内容はそのまま)
  5. shscreens.py の 541 行目と 576 行目それぞれにある /// に変更。変更後はこうなります: idx_line, idx_column = idx // (ncolumns + 1), idx % (ncolumns + 1)
  6. StaSh で ssh3 を実行

vk_tapped の変更後はこちら。Python 3 のコードに変換後の行数で、242~262 の部分になります。内容としては、vk.name を全て vk にし、'k_tab' 等となっていた部分を対応した数値に置き換えています。この変更により、StaSh のバーチャルキーボードで Tab や Up、CC 等をタップしたときに、SSH 接続先にも正しいキーコード (それぞれタブ、カーソル上、Control + C) が送られるようになります。

    def vk_tapped(self, vk):
        if vk == 7:
            self.send('\t')
        elif vk == 0:
            self.kc_pressed('C', CTRL_KEY_FLAG)
        elif vk == 1:
            self.kc_pressed('D', CTRL_KEY_FLAG)
        elif vk == 6:
            self.kc_pressed('U', CTRL_KEY_FLAG)
        elif vk == 9:
            self.kc_pressed('Z', CTRL_KEY_FLAG)
        elif vk == 2:
            self.kc_pressed('UIKeyInputUpArrow', 0)
        elif vk == 3:
            self.kc_pressed('UIKeyInputDownArrow', 0)

        elif vk == 10:
            if _stash.terminal.is_editing:
                _stash.terminal.end_editing()
            else:
                _stash.terminal.begin_editing()

出ていたエラーと解決のためのヒント

実際に ssh が動くようになるまでに行った手順としては、上のステップ 3 が最後になります。自分が最初にぶちあたったのは、ステップ 4の shscreens.py を Python 3 に変換した後で、エラーはこちらです:

system/shscreens.py", line 578, in load_pyte_screen
    c = pyte_screen.buffer[idx_line][idx_column]
TypeError: list indices must be integers or slices, not float

小数 (float) になっているのが問題と言うことなので、元の idx_line と idx_column を int() で整数にしてから呼び出されるようにしても解決せず、以下ページがヒント (とういか答え) となりました。

My guess would be that stash uses / division for line/column indices. On Python 3 / always produces a float. The fix is simple: replace it with flooring division //.

https://github.com/selectel/pyte/issues/123

ステップ 3 の変更を加える事になった原因のエラーはこちらです:

  File "stash_extensions/bin/ssh3.py", line 230, in vk_tapped
    if vk.name == 'k_tab':
AttributeError: 'int' object has no attribute 'name'

これは StaSh 自体のコードに関わる内容だと思うんですが、よくわかりません。ここをいじらなくても、SSH セッション自体は張れます。この関数の目的は、押された vk (=virtual key) に対応したキーコードを SSH 接続先に送るということです。なので、関数直下に print(vk) を差し込み、SSH 接続した状態で Tab やら CC やらを押して Console に表示される数字に name の値を置き換えていきました。美しい解決方法を探ったのですが諦めました。

さて、そもそも今回 ssh コマンドを動かしてやろうという動機付けになったのは、StaSh の説明の中にあった一文、特に色を付けた部分でした。

StaSh works with both Pythonista 2 and 3, though not all commands support python3. (訳: StaSh は Pythonista 2 でも 3 でも動きますが、全てのコマンドが python3 対応にはなっていません)

https://github.com/ywangd/stash

Image by Stable Diffusion

ここからは本文に関係ありません。今回のアイキャッチ画像は、Mac 用 Stable Diffusion クライアントの Mochi Diffusion で出力した画像に、後から文字を描き足したモノです。 Stable Diffusion を使った場合は、情報を記載するようにします。

Date:
2023年5月6日 22:31:24

Model:
realisticVision-v20_split-einsum

Size:
512 x 512

Include in Image:
cartoon, a young man waring glasses, super happy

Exclude from Image:


Seed:
3826992198

Steps:
20

Guidance Scale:
11.0

Scheduler:
DPM-Solver++

ML Compute Unit:
CPU & Neural Engine

3年以上の時を経て、Pythonista 3 がバージョン 3.4 にアップデート (Python 3.10 サポート)

もう終わったのかと思っていたけど、、、うれしかった!

iPad で実行。Stash の version コマンドの出力。Python 3.10.4 になってます

Python 3 は 3.10.4 にアップデート。Python 2 は完全廃止

iOS で Python コードを書いて実行できるアプリ、Pythonista 3。3年以上の時を経て Python 3.10 対応となってアップデートされました。

Pythonista 3 ←App Storeへのリンク

詳しい変更内容は、以下のリリースノートを見てください。Google 日本語翻訳のリンクも貼っておきます。

https://omz-software.com/pythonista/docs-3.4/py3/ios/new.html

プラス要素だけでは無く、本バージョンでは Python 2.7 が無くなりました。なので、過去記事で書いた 2.x 環境用で動くスクリプトは、そのままでは実行できなくなりました。StaSh では ssh コマンドも動きません。

StaSh の話が続きますが、StaSh は有志の方々によって開発されている OSS のため、対応が追いついていません。やっとなんとかインストール・実行できるようになりましたが、エイリアスや環境変数を書き込める .stashrc ファイルや、複数のコマンドをセミコロンでつなげて一度に実行しようとしても、最初のコマンドしか実行されない状況です。

StaSh のインストール

StaSh をインストールして正しく動作させるには、一度 Pythonista 3 を削除することが推奨されています (StaSh 自体やインストール方法などは日々アップデートされているようなので、定期的に Github をチェックすることをお勧めします)。現在のところ、自分で試した感じでは dev バージョンをインストールするのが良さそうです。Console に以下をコピペして実行してください。

url = 'https://raw.githubusercontent.com/ywangd/stash/dev/getstash.py'; import requests as r; exec(r.get(url).text.replace('master', 'dev'))

その後、一度 Pythonista 3 アプリを終了後、This iPhone (Documents フォルダ) にある launch_stash.py を実行すると StaSh が立ち上がります。

Django のインストールと実行 (最新版は動かない)

Django は、試したところ version 4.0 ならインストールとテストページの表示までできました。バージョンを指定しないと 4.2.1 が入るのですが、そのバージョンでは openssl_md5 のシグナチャが見つからないというようなエラーで django-admin が動きません。

pip install django==4.0

ちなみに、StaSh に表示されるインストールログや、pip show Django を見ると 4.2.1 がインストールされているように表示されるのですが、Console で確認 ( import django してから print(django.__version__) ) すると 4.0 です。pip のバージョン表示はこれまで通り信用できないようです。

ともあれ無事インストールできたら、Pythonista 3 を終了して再度立ち上げ、プロジェクトを作ります。

django-admin startproject mysite

右にスワイプして This iPhone > mysite と進み、manage.py をタップしてコードを開きます。▷を長押しして Arguments に以下をコピペし、Run しましょう。noreload の左にあるのは、マイナス二つです。

runserver --noreload

赤文字の英語で「CommandError: You must set settings. ALLOWED_HOSTS if DEBUG is False.」と出た場合は、ここではとりあえず気にせず Pythonista 3 を終了・起動、そしてもう一度 manage.py を Run しましょう。iOS がネットワークアクセスの可否を聞いてきたら許可してください。

うまくいけば Console に諸々の注意事項と共に URL http://127.0.0.1:8000/ が表示されるはずです。こちらをタップするなり Safari にコピペするなりすると、はい、おめでとうございます、ロケットページが表示されます。 (このサイトには過去バージョンの Pythonista 3 の記事がいくつかあるので、参考に見てみてください)。

とりあえずのまとめ

最近 a-Shell という Unix/Linux ライクなシェル環境で Python 3.11 がいじれる iOS アプリを見つけていたのですが、Python がバックグラウンドで動き続けない (Django や Flask アプリは、ブラウザとアプリを行き来しないとページが更新できない) ことにがっかり (← いじっているうちになぜか解決しました)。そんな矢先に届いたのが Pythonista 3 のアップデートでした。個人的に新しめの Python ならではの機能はあまり使っていないのですが、これを機に知識のアップデートもしていこうと思っています。StaSh がキャッチアップするのにまだかかりそうではありますが、新たな発見があれば書きためていこうと思います。

Image by Stable Diffusion

ステップ数が少ないからかなり怖い画像になってますが、Mochi Diffusion の max 値である 50にすると、変にまとまってしまって自分のうれしい気持ちを表現しきれないので、最初に出力した画像をアイキャッチにしました。ゾッとした方、ごめんなさい。

Date:
2023年5月6日 14:35:09

Model:
realisticVision-v20_split-einsum

Size:
512 x 512

Include in Image:
cartoon, people happy with a new release of software

Exclude from Image:


Seed:
3343127351

Steps:
20

Guidance Scale:
11.0

Scheduler:
DPM-Solver++

ML Compute Unit:
CPU & Neural Engine
© Peddals.com