出来ました。ダービーと目黒記念の予想を掲載しました
Pyxelで作成した競馬予想ビューアをGitHub Pages上で動作させる際、index.jsonは取得できるものの、レースデータ(json)の読み込みに失敗する問題が発生した。また、ローカル版とWeb版でファイル読み込み方式が異なるため、それぞれ別の問題が存在していた。
起動時に
「jsonが見つかりません」
と表示される。
Web版では os.walk() によるディレクトリ走査が利用できない。
ローカル版では DATA フォルダを直接検索できるが、GitHub Pages上ではサーバー側のディレクトリ一覧取得機能が存在しないため、ファイル一覧を取得できなかった。
DATA/index.json を作成し、利用可能な予想ファイル名一覧を格納する方式へ変更。
例
[
"260531_東京芝2400m_東京優駿_予想中.json","260531_東京芝2500m_目黒記念_予想中.json"
]
cannot import name 'to_py' from pyodide.ffi
Pyodideの新しいバージョンでは
from pyodide.ffi import to_py
が廃止されていた。
js_obj.to_py()
を使用する方式へ変更。
レース一覧は表示されるが、選択すると
「読込中...」
が一瞬表示された後、
PythonError : pyodide.ffi.JsException
で失敗する。
JavaScriptのfetchを直接利用していた。
promise = js.fetch(url)
promise
.then(create_proxy(on_response)).then(create_proxy(on_json))
.catch(create_proxy(on_error))
Pyodide + Promise + Pyxel の updateループとの相性問題により、Promise解決後のコールバックが正常に実行されない場合があった。
また、
resp.json()
↓
JavaScript Object
↓
to_py()
↓
Python Object
という変換処理も不安定要素となっていた。
Pyodide公式推奨の pyfetch を使用。
import pyodide.httpimport asyncio
async def _do_fetch():
response = await pyodide.http.pyfetch(url)text = await response.string()self.result = json.loads(text)self.state = self.STATE_DONE
asyncio.ensure_future(_do_fetch())
JavaScript Promiseを直接扱わない。
JS Object → Python Object の変換が不要。
JSON文字列として取得し、
json.loads()
でPython側のみで処理できる。
Pyodideのイベントループと自然に統合されるため安定して動作する。
urlopen error
が発生する。
ローカルファイルを
urllib.request.urlopen()
で読み込もうとしていた。
urlopen() はURL向けであり、
C:\DATA\race.json
のような通常ファイルパスには適していない。
ローカル版は通常のファイル読み込みへ変更。
with open(path, "r", encoding="utf-8") as f:data = json.load(f)
pyodide.http.pyfetch()
↓
response.string()
↓
json.loads()
open()
↓
json.load()
問題の本質はGitHub PagesやJSONファイル配置ではなく、
「Pyodide + Promise + Pyxel」
の非同期処理の組み合わせだった。
Pyodide環境では
js.fetch()
よりも
pyodide.http.pyfetch()
を利用し、Python側で async/await を用いて処理する方が圧倒的に安定する。
今後PyxelのWebアプリを作成する際は、
「pyfetch + asyncio + json.loads」
を標準構成とする。
PR
Free Space
Calendar
Comments
Freepage List