HTMLファイル内にPythonのコードを記述するツール「PyScript」を使ってみた
PyScript とは
PyScript
は、Python
のコードをhtml
ファイル内に記述することで、Python
のコードを実行できるようにするツールである。
PyScript を使ってみた
下記のようにhtml
ファイル内にPython
のコードを記載することで、Python
のコードを実行できる。
作成したhtml
ファイルをブラウザを開くことで、実行結果を確認できる。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link
rel="stylesheet"
href="https://pyscript.net/releases/2023.11.2/core.css"
/>
<script
type="module"
src="https://pyscript.net/releases/2023.11.2/core.js"
></script>
</head>
<body>
<script type="py" terminal>
# ここにPythonのコードを記述
print("Hello, World!")
print("\n")
for i in range(10):
print(str(i) + "こんにちは")
</script>
</body>
</html>
ToDo アプリを作成してみる
公式サイトのexampleを参考に、ToDo アプリを作成してみる。
1. ファイルの作成
コードを記述するためのhtml
ファイルと、Python
のコードを記述するためのmain.py
を作成した。
2. Web サーバーの起動
ローカルのhtml
ファイルをブラウザで開くと、main.py
を読み込むことができないため、Web サーバーを起動する必要がある。
ローカルの web サーバーを起動し、html
ファイルをブラウザで開いた。
ちなみに私は、Simple Web Serverを使用した。
3. ToDo アプリの動作確認
問題なく動作した。
メリットとデメリット
メリット
- 簡単に
Python
のコードを実行できる -
html
ファイル内に簡単にpython
の処理を組み込むことができる。
デメリット
-
自動コード整形との相性が悪い
html
ファイル内にPython
のコードを記載することになるが、自動コード整形によって改行やインデントが削除されることがある。例えば、下記のコードは日時を取得して画面上に表示させるコードである。
<py-script> from datetime import datetime now = datetime.now() display(now.strftime("%m/%d/%Y, %H:%M:%S")) </py-script>
このコードを自動整形すると、下記のよう改行が削除され、正しく動作しなくなる。
<py-script> from datetime import datetime now = datetime.now() display(now.strftime("%m/%d/%Y, %H:%M:%S")) </py-script>
Python
のコードは、インデントや改行も重要な意味を持つため、自動整形によって改行が削除されると、コードが正常に動作しなくなる。python
のコードは別ファイルに記述し、html
ファイルから読み込むようにした方が良い。 -
手の込んだ機能を実装しようとすると
Python
のコードが複雑になり可読性が悪くなる
PyScript を使ってみての感想
-
プログラミング初学者が使用する観点
あまりおすすめできない。
PyScript
はプログラミング初学者にpython
の実行環境を簡単に提供することができるが、Google Colaboratory
でも同様にpython
の実行環境を提供することができる。Google Colaboratory
の方が、PyScript
よりも UI が良く、直感的に操作できると思う。 -
実利用の観点
html
ファイルにちょっとしたPython
の処理を組み込むという観点では、PyScript
は良いツールだと思う。(例: 簡単な計算など)
しかし、簡単な計算などはJavaScript
でも実装できるため、PyScript
を使用する必要性はあまり感じない。また、
PyScript
を使用して、本格的な web アプリを作成するという観点では、PyScript
は向いていないと思う。逆に難易度が高くなると感じた。
Web アプリを作成する場合は、Django
やFlask
などのフレームワークを使用した方が良いと思う。
まとめ
PyScript
は、html
ファイル内にPython
のコードを記述することで、Python
のコードを実行できるようにするツールである。
簡単にPython
のコードを実行できるため、簡単な計算などを行う際には便利だと思うが、本格的な web アプリを作成する際には、PyScript
を使用する必要性はあまり感じない。
現時点では、使用する機会はないと思う。
ToDo アプリのコード
<!DOCTYPE html>
<html>
<head>
<!-- Recommended meta tags -->
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<!-- PyScript CSS -->
<link
rel="stylesheet"
href="https://pyscript.net/releases/2024.1.1/core.css"
/>
<!-- CSS for examples -->
<link rel="stylesheet" href="./assets/css/examples.css" />
<!-- This script tag bootstraps PyScript -->
<script
type="module"
src="https://pyscript.net/releases/2024.1.1/core.js"
></script>
<!-- for splashscreen -->
<style>
#loading {
outline: none;
border: none;
background: transparent;
}
</style>
<script type="module">
const loading = document.getElementById("loading");
addEventListener("py:ready", () => loading.close());
loading.showModal();
</script>
<title>Todo App</title>
<link rel="icon" type="image/png" href="./assets/favicon.png" />
<style>
.line-through {
text-decoration: line-through;
}
</style>
</head>
<body>
<dialog id="loading">
<h1>Loading...</h1>
</dialog>
<section class="pyscript">
<main>
<section>
<div>
<h1>To Do List</h1>
</div>
<div>
<input id="new-task-content" type="text" />
<button id="new-task-btn" type="submit" py-click="add_task">
Add task
</button>
</div>
<div id="list-tasks-container"></div>
<template id="task-template">
<section class="task py-li-element">
<label class="flex items-center p-2">
<input style="vertical-align: middle;" type="checkbox" />
<p style="display: inline;"></p>
</label>
</section>
</template>
</section>
</main>
<script type="py" src="./main.py"></script>
</section>
</body>
</html>
from datetime import datetime as dt
from pyscript import document
from pyweb import pydom
tasks = []
def q(selector, root=document):
return root.querySelector(selector)
# define the task template that will be use to render new templates to the page
# Note: We use JS element here because pydom doesn't fully support template
# elements now
task_template = pydom.Element(q("#task-template").content.querySelector(".task"))
task_list = pydom["#list-tasks-container"][0]
new_task_content = pydom["#new-task-content"][0]
def add_task(e):
# ignore empty task
if not new_task_content.value:
return None
# create task
task_id = f"task-{len(tasks)}"
task = {
"id": task_id,
"content": new_task_content.value,
"done": False,
"created_at": dt.now(),
}
tasks.append(task)
# add the task element to the page as new node in the list by cloning from a
# template
task_html = task_template.clone()
task_html.id = task_id
task_html_check = task_html.find("input")[0]
task_html_content = task_html.find("p")[0]
task_html_content._js.textContent = task["content"]
task_list.append(task_html)
def check_task(evt=None):
task["done"] = not task["done"]
task_html_content._js.classList.toggle("line-through", task["done"])
new_task_content.value = ""
task_html_check._js.onclick = check_task
def add_task_event(e):
if e.key == "Enter":
add_task(e)
new_task_content.onkeypress = add_task_event
Discussion