Python 코드를 웹에서 직접 실행할 수 있으면 편할 것입니다. PHP나 Django에서 파이썬 스크립트 파일을 실행하는 방법이 아니라, JavaScript처럼 HTML 파일에 직접 파이썬 스크립트를 포함시켜서 실행하는 방법을 설명합니다. 이를 위한 프로젝트로 Pyodide가 있는데요, PyScript로 훨씬 간편하게 할 수 있습니다.
아래 코드를 html로 저장하고 웹브라우저에서 열어 봅시다.
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
print('Hello, World!')
</py-script>
</body>
</html>
화면 왼쪽에 Hello, World!라는 문구가 나타납니다.
print
문이 작동했다는 사실에 살짝 놀랄 수도 있습니다만, <body>
태그 안에 그냥 문자열을 넣으면 더 간단한데 이런 코드가 무슨 의미가 있냐고 생각할 수도 있습니다. 이 코드만 보면 파이썬인지 다른 언어인지도 확실치 않습니다. 그래서 계산을 하는 예시를 보겠습니다.
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
print("π를 계산해 봅시다:")
def wallis(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = wallis(100000)
s = f"π는 대략 {pi:.3f}입니다."
print(s)
</py-script>
</body>
</html>
드디어 익숙한 파이썬 코드가 등장했습니다. 월리스 공식을 이용하여 π의 근사값을 계산합니다. 3.142라는 결과가 아쉽다면 n을 늘리고 출력할 부동소수점의 길이를 늘려주면 됩니다.
이제 py-script
태그만 있으면 파이썬 코드를 돌릴 수 있습니다. 그런데 웹페이지에서 print
만 쓸 수는 없겠지요. 자바스크립트처럼 웹페이지의 구성요소와 상호작용할 수 있을까요?
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<b><p>오늘 날짜는 <u><label id='today'></label></u></p></b>
<br>
<div id="pi" class=" -primary"></div>
<py-script>
import datetime as dt
pyscript.write('today', dt.date.today().strftime('%A %B %d, %Y'))
def wallis(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = wallis(100000)
pyscript.write('pi', f'π는 대략 {pi:.3f}입니다.')
</py-script>
</body>
</html>
페이지를 처음 열 때에는 "오늘 날짜는"만 보이고 잠시 후 <label>
이 업데이트되는 것을 확인할 수 있습니다. 코드를 보면 import
가 작동한다는 사실도 확인할 수 있습니다. 혹시 기본이 아닌 패키지도 불러올 수 있을까요? 그렇다면 정말 좋을 텐데요.
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js">
</script>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-config>
packages = ["matplotlib", "pandas"]
</py-config>
<py-script>
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
display(fig, target="plot")
</py-script>
</body>
</html>
numpy
, matplotlib
등도 불러와서 그림을 그려 줍니다. 이미 파이썬을 개발하던 분들이면 이 부분에서 살짝 놀랄 수도 있습니다. 이 예제를 실행하는 http 서버에 이 패키지들을 설치 안 한 상태에서도 되거든요.
그렇다면 pypi에 없는 whl은 될까요? <py-config>
에 whl 파일의 경로를 적어 주면 됩니다. 아래에 예시가 있습니다:
<py-config>
packages = ["./static/wheels/travertino-0.1.3-py3-none-any.whl"]
</py-config>
HTML 하나에 파이썬 코드 전체를 적을 수 없는 경우도 있을 텐데요, 다행히 .py 파일도 불러올 수 있습니다. <py-config>
에 paths
항목에 적어 주면 됩니다.
아래처럼 data.py
파일을 먼저 준비하고요,
import numpy as np
def make_x_and_y(n):
x = np.random.randn(n)
y = np.random.randn(n)
return x, y
HTML 파일은 아래와 같습니다.
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-config>
packages = ["matplotlib", "pandas"]
[[fetch]]
files = ["./data.py"]
</py-config>
<py-script output="plot">
import matplotlib.pyplot as plt
from data import make_x_and_y
x, y = make_x_and_y(n=1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
display(fig, target="plot")
</py-script>
</body>
</html>
결과는 앞의 플롯 그리기와 같습니다. 다만, 이 예제는 이전에 설명한 다른 예제와 달리 로컬에서 실행하면 Cross origin requests are only supported for HTTP
등의 에러가 발생할 수 있습니다. 웹서버를 준비하고 서버에서 실행해주세요. 참고로 파이썬에서 http 서버를 띄우기 가장 간단한 방법은 python -m http.server 포트번호 --bind IP주소
로 띄우는 것입니다. 상용 성능은 아니지만 디버깅용으로 편리합니다. 이렇게 띄운 뒤에 IP주소:포트번호
로 웹브라우저에서 접속하면 실행한 디렉토리가 보일 것입니다. 여기서 html
파일을 선택해서 보면 됩니다.
지금까지 PyScript에 대해서 알아보았습니다. 그런데 pyscript.js
, css
를 일일이 서버에서 받아오고 있었습니다. 자신의 서버에서 직접 제공할 수 있을까요?
PyScript 홈페이지에서 다운로드하고 압축을 풀면 Install이 필요 없다는 설명과 달리 바로 사용할 수 있는 상태가 아닙니다. (물론 https://pyscript.net/latest로 연결하면 됩니다만, 이는 앞으로 바뀔 수 있습니다. 실제로 이 글을 처음 작성할 때에는 주소가 alpha
였는데 지금은 latest
로 바뀌었습니다) 따라서 빌드가 필요합니다.
우선 node가 없으면 설치해야 하고요, npm으로 빌드합니다. 빌드 방법은 pyscriptjs/README.md
에 적혀 있으니 그대로 따라하면 됩니다. 빌드가 완료되면 pyscriptjs/examples/build
에 pyscript.js
, css
파일이 생기니 이를 링크해서 쓰면 됩니다. pyscriptjs/examples
에는 다양한 예제가 있는데요, build 디렉토리가 pyscriptjs/build
라고 가정하고 작성한 코드이므로 build 디렉토리를 옮기고 여는 것이 좋습니다.
※ 모든 예제의 원본은 https://github.com/pyscript/pyscript/blob/main/GETTING-STARTED.md 페이지에 있습니다.
좋은 글이네요. 공유해주셔서 감사합니다.