HOWTO · Python

HTML에서 Python 실행

HTML에서 Python을 실행하는 방법 알아보기

이 페이지의 내용

스크립트를 정적 HTML에 넣는 것만으로는 브라우저에서 서버 측 Python이 실행되지 않습니다. Python으로 만든 콘텐츠를 표시하려면 서버에서 Python을 실행하고 그 결과를 HTTP 응답으로 보내야 합니다. 소규모로 연동할 때는 PHP 애플리케이션에서 Python 프로세스를 시작할 수 있고, Django 애플리케이션에서는 보통 뷰에서 템플릿으로 데이터를 전달합니다.

PHP로 HTML에서 Python 스크립트 실행하기

.php처럼 PHP가 처리하는 확장자로 페이지를 저장하고, PHP가 설정된 서버에서 제공하세요. 서버에는 Python 인터프리터도 설치되어 있어야 하며, 해당 인터프리터를 실행할 권한이 필요합니다. 다음 독립 실행형 예제는 짧은 Python 스크립트를 만들고, 두 인수를 안전하게 전달한 뒤, 캡처한 결과를 응답에 넣습니다:

<?php
$pythonScript = <<<'PY'
import sys

name = sys.argv[1]
count = int(sys.argv[2])
print(f"Hello, {name}! Count: {count}")
PY;

$scriptPath = tempnam(sys_get_temp_dir(), 'page-python-');
file_put_contents($scriptPath, $pythonScript);
$command = 'python3 ' . escapeshellarg($scriptPath)
    . ' ' . escapeshellarg('Mina')
    . ' ' . escapeshellarg('3');
$result = shell_exec($command);
unlink($scriptPath);

?><!doctype html>
<html lang="en">
  <body>
    <p><?= htmlspecialchars($result ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></p>
  </body>
</html>

여기서 PHP는 python3을 시작하고, Python 프로세스는 Mina와 3을 각각 sys.argv[1]과 sys.argv[2]로 받습니다. shell_exec()는 프로세스 출력을 캡처하고, htmlspecialchars()는 그 출력을 페이지에 삽입하기 전에 인코딩합니다. 이 내용은 서버 콘솔에 출력되는 텍스트가 아니라 브라우저로 전송되는 응답 내용입니다.

PHP 호스트에서 shell_exec()를 사용할 수 있도록 설정해야 하며, 웹 서버 계정에는 인터프리터를 실행할 권한이 있어야 합니다. 이 예제는 고정된 인수를 사용합니다. 동적인 값을 전달할 때는 값을 검증하고 escapeshellarg()로 인수를 각각 이스케이프하세요. 신뢰할 수 없는 입력을 셸 명령에 이어 붙이지 마세요. 규모가 큰 애플리케이션에서는 요청마다 프로세스를 시작하는 대신 작업 큐나 전용 서비스를 사용하는 편이 더 적합할 수 있습니다.

Django로 HTML에서 Python 스크립트 실행하기

Django 애플리케이션에서는 애플리케이션 로직을 Python 뷰에 두고 그 결과를 템플릿에 전달합니다. 템플릿은 서버에서 해당 값을 HTML로 렌더링합니다. 브라우저는 렌더링된 페이지를 받으며 Python을 실행하지 않습니다. 예를 들어 뷰에서 context = {"message": "Hello from Django"}를 준비해 render(request, "page.html", context)를 반환하고, 템플릿에서는 {{ message }}로 값을 표시할 수 있습니다.

템플릿에서 재사용할 표시 로직이 필요하다면 사용자 정의 템플릿 태그를 사용할 수 있습니다. core라는 앱이 설치되어 있다고 가정하고 core/templatetags/__init__.py와 core/templatetags/my_custom_tags.py를 만듭니다. 두 번째 파일에서는 django에서 template을 가져오고 register = template.Library()를 설정한 다음, @register.simple_tag로 장식한 함수(예: def greeting(): return "Hello from Django")를 정의합니다. Django가 templatetags 패키지를 찾도록 추가한 뒤 개발 서버를 다시 시작하세요.

템플릿에서 {% load my_custom_tags %}로 모듈을 불러오고 {% greeting %}으로 태그를 호출합니다. 이 태그는 서버 측 템플릿 렌더링에 사용할 텍스트를 반환합니다. 브라우저의 HTML에서 임의의 Python을 실행하는 것은 아닙니다. 간단한 값을 표시할 때는 사용자 정의 태그보다 뷰와 템플릿 컨텍스트를 사용하는 편이 대체로 더 명확합니다. Django에는 date, linebreaks, safe, random과 같은 기본 필터도 있습니다. 자세한 내용은 Django 기본 템플릿 필터 참조를 확인하세요.

페이지가 로드된 뒤 데이터가 필요하다면 Django 뷰를 엔드포인트로 제공하고 fetch()나 다른 AJAX 클라이언트로 요청하세요. 민감한 데이터를 반환하거나 작업을 수행하기 전에 인증과 권한을 확인해야 합니다. 상태를 변경하는 POST 요청에는 Django의 CSRF 보호를 사용하고 CSRF 토큰을 보내세요. 엔드포인트를 POST 요청으로만 제한해도 보안이 보장되는 것은 아닙니다. 자세한 내용은 Django CSRF 문서를 참조하세요.

PHP 호스팅 사이트에 기존 Python 스크립트를 소규모로 연동하고 호스트가 허용한다면 PHP에서 프로세스를 호출하는 방법을 선택하세요. Django 애플리케이션에서는 뷰와 템플릿으로 페이지 데이터를 계산하고 렌더링하는 것이 일반적입니다. 템플릿에서 표시 로직을 재사용하려면 사용자 정의 태그를, 페이지가 로드된 뒤 요청할 데이터에는 엔드포인트를 사용하세요.