[Python] error: CGI의 ModuleNotFoundError 에러 해결하기

정진용·2024년 4월 29일
0

CGI (Common Gateway Interface)에서 ModuleNotFoundError 에러 해결하기

error

[Tue Apr 30 03:22:05.126457 2024] [cgi:error] [pid 3100:tid 1252] [client ::1:53822] AH01215: Traceback (most recent call last):\r: C:/wamp64/www/index.py
[Tue Apr 30 03:22:05.126457 2024] [cgi:error] [pid 3100:tid 1252] [client ::1:53822] AH01215:   File "C:\\wamp64\\www\\index.py", line 6, in <module>\r: C:/wamp64/www/index.py
[Tue Apr 30 03:22:05.126457 2024] [cgi:error] [pid 3100:tid 1252] [client ::1:53822] AH01215:     import cgi, os, view, html_sanitizer\r: C:/wamp64/www/index.py
[Tue Apr 30 03:22:05.126457 2024] [cgi:error] [pid 3100:tid 1252] [client ::1:53822] AH01215: ModuleNotFoundError: No module named 'html_sanitizer'\r: C:/wamp64/www/index.py

요약:

import cgi, os, html_sanitizer
  • 문제 발생: The Python Package Index (PyPI)에서 html_sanitizer 모듈을 다운 받아서 CGI를 통해 웹페이지 보안 강화에 사용하려고 함
    => 로컬(VSCode)에서 해당 모듈을 성공적으로 import하여 코드 제작 완료
    => CGI로 파이썬 코드를 실행하니 빈 화면 출력
    => apache_error.log 파일을 확인해보니 위와 같이 ModuleNotFoundError 출력
    => CGI에서 html_sanitizer 모듈을 찾지 못해서 발생하는 문제
  1. 첫 번째 의문점: 로컬의 파이썬과 CGI의 파이썬이 참조하는 경로가 다른가?
    • 해결 방안 1: 참조 경로를 조사하는 코드인 import sys; print(sys.path)을 로컬과 CGI에서 각각 실행하기
      => CGI가 참조하는 경로는 로컬 파이썬 경로와 많이 다르며 환경변수의 영향을 받지 않았다.
  2. 두 번째 의문점: CGI의 파이썬의 sys.path에 원하는 경로를 추가하자!
    • 해결 방안 2(실패): sys.path.append("C:\원하는\경로\삽입")를 CGI로 실행시키기.
      => CGI에서 sys.path를 확인했을 때 해당 경로가 추가되지 않았다.
  3. 세 번째 의문점: .pth 파일로 참조 경로를 영구적으로 추가하기?
    • 해결 방안 3(성공!): Python을 설치한 폴더에서 Lib 폴더 안에 있는 site-packages 경로로 접근
      내 경우, C:\Program Files\Python312\Lib\site-packages
      아무이름으로 .pth 파일을 만들고, (예를 들어, mypythonpath.pth) 그 안에 추가할 path를 적어 준다.
      내 경우, C:\Users\Jin-Yong\AppData\Roaming\Python\Python312\site-packages

error solved


문제 해결 과정

ModuleNotFoundError 에러에 대해

import 시 해당 모듈을 찾을 수 없을 때 발생하는 오류.

프로그램이 참조하는 경로에 모듈이 없을 때,
프로그램이 참조하는 경로에 '모듈과 같은 이름을 갖지만 유효하지 않은 파일(이전 버전 등)'이 존재할 때 발생한다.

1. 첫 번째 의문점: 로컬의 파이썬과 CGI의 파이썬이 참조하는 경로가 다른가?

로컬에선 잘 작동했으니, CGI가 참조하는 경로에 문제가 있을 거라고 예상했다.

해결 방안 1: 참조 경로를 조사하는 코드인 import sys; print(sys.path)을 로컬과 CGI에서 각각 실행하기

이 문제에 관해 구글링을 하다가, 나와 같은 문제를 겪은 stackoverflow 질문글을 찾았다.

before_solving

글에 나온 대로 import sys; print(sys.path)를 로컬[왼쪽]과 CGI[오른쪽]의 파이썬에 각각 실행했더니, 결과가 많이 달랐다. [신기하니 당장 확인해보길 바라요~!]
환경변수도 수정해봤는데, CGI가 참조하는 경로는 환경변수의 영향을 받지 않았다.

Apache 튜토리얼 공식 문서에도 같은 얘기를 하며 사용자에게 주의를 주고 있다. [웹서버다 보니 조심스러운 면이 있나보다.]


2. 두 번째 의문점: CGI의 파이썬의 sys.path에 원하는 경로를 추가하자!

로컬 파이썬에서 하는 것처럼, sys.path.append()로 참조 경로를 추가하면 되지 않을까?

해결 방안 2(실패): sys.path.append("C:\원하는\경로\삽입")를 CGI로 실행시키기.

실행 이후 CGI에서 sys.path를 확인했을 때 해당 경로가 추가되지 않았다. [이거 아주 똥고집일세]


3. 세 번째 의문점: .pth 파일로 참조 경로를 영구적으로 추가하기?

나와 같은 문제를 겪은 stackoverflow 질문글에서 제시한 해결책을 사용해보자.

- 해결 방안 3(성공!): Python을 설치한 폴더에서 Lib 폴더 안에 있는 site-packages 경로로 접근

질문글에서는 distutils라는 모듈을 사용하라고 했는데, 지금은 해당 모듈을 사용할 수 없다. [2012년 글이니 그럴 만도 하다 ㅠ]

나는 이전에 삽질하다 이미 알게 된 경로였지만, 어떻게 설명해야 하나 고민하던 차에 나름 직관적인 설명의 한글 블로그 글을 찾았다. 파이썬 경로 추가 방법 (반영구적, 영구적)

여기에 나와 있는 대로 설명하자면,
1. Python을 설치한 폴더에서 Lib 폴더 안에 있는 site-packages 경로로 접근
내 경우, C:\Program Files\Python312\Lib\site-packages
2. 아무이름으로 .pth 파일을 만들고, (예를 들어, mypythonpath.pth) 그 안에 추가할 path를 적어 준다.
내 경우, C:\Users\Jin-Yong\AppData\Roaming\Python\Python312\site-packages

이렇게 하니...
error solved
성공!!!

after_solving
이렇게 하니까 CGI의 sys.path에도 원하는 경로가 추가되었고, 다운 받은 모듈이 성공적으로 import됐다.


참고 자료

나와 같은 문제를 겪은 stackoverflow 질문글

파이썬 경로 추가 방법 (반영구적, 영구적)


내 이야기 (넘어가셔도 됩니다)

생활코딩 WEB2 Python 강의 수강을 완료했다.
강의 막바지에 다시 ModuleNotFoundError를 만나서 반가웠다. 아니다

처음에는 흰 화면만 뜨길래 문법 오류인 줄 알고 모니터만 한참 들여다 봤다. Apache 에러 로그 보는 게 익숙치 않았기 때문이다.
급한 대로 (확실한 참조 경로였던) www 폴더에 모듈 파일을 복붙해서 해결하긴 했는데, 근본적인 해결책이 아니라 너무 찝찝했다.

강의를 마저 듣고 다시 돌아와서 에러를 마주했다.
삽질을 좀 하다가, 로컬 파이썬에서 코드가 돌아가는 걸 확인했다. 다시 정신차리고 Apache 에러 로그랑 친해지려는 시도를 했다.

그래도 이전의 시행착오 덕에 확실히 더 능숙하게 오류를 해결한 것 같다.
sys.path를 cgi로 출력하는 접근 방법을 바로 생각하지 못한 게 좀 아쉽다.

포스팅을 할까말까 고민했는데, 하길 잘했다는 생각이 든다.
내용을 일목요연하게 전달하는 능력은 부족하지만, 내 머릿속에는 확실히 정리가 됐다.

강의를 하나하나 끝마칠수록 들어보고 싶은 강의가 많아진다. 대학생 때는 이런 적이 있었나 싶다.

어떤 프로그램을 만들겠다는 목표를 가지고 방향성있는 노력을 하고 싶은데, 아직 딱 어떤 프로그램을 만들고 싶다는 생각은 들지 않는다.
그래도 서서히 윤곽이 잡히는 게 느껴진다. 더 정진해보자.


생각해 볼 것들

  • 직관적으로 에러 원인을 확인할 수 있는 방법을 최우선으로 생각하자.

  • .pth 파일을 통해 영구적으로 참조 경로를 추가하는 방법을 알게 됐다.

  • 확실히 영어로 찾아야 해결의 실마리가 보인다.

0개의 댓글