#1. 수강 과목 : Python(파이썬과 웹 ; cgi)
#2. 수강 콘텐츠 : 생활코딩

  1. 실습환경 조성 : 웹서버 준비(비트나미 설치 및 작업 라이브러리 설정)

  2. 사전 작업 : conf에 httpd.conf 중 mod_cgi에 #을 없애고

<Directory "/Applications/mampstack-7.1.14-0/apache2/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
    <Files *.py>
      Options ExecCGI
      AddHandler cgi-script .py
    </Files>
</Directory>

상태를 만든다. 이후 비트나미 서버를 리셋한다.

  1. index.py를 localhost:8080/index.py로 띄우기 : 여기서 따로 파일 안 만들고 바로 htdocs 폴더에 index.py를 만들어야 제대로 뜬다. 여기서 shebang라인에 파이썬의 정확한 경로를 적어주고 나머지 부분은 독스트링으로 print 처리 해준다. 대략 이런 코드다.
#!/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
print("Content-Type: text/html; charset=UTF-8\n")
print()
print('''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
... '''

준비 과정까지 거의 1시간 반은 걸린 것 같다.. 웹서버쪽만 들어가면 어려워진다.


  1. Query string 값을 파이썬의 값으로 알아내는 방법.
    페이지는 변하지 않으면서 링크 클릭 시 url의 id값이 바뀌고 화면이 전환되는 것(html에서 파일간 이동하는 것처럼 하되 실제 파일이 이동하는 것이 아니라 id값만 이동하는 과정)

상단부

import cgi
form = cgi.FieldStorage()
pageId = form["id"].value

하단부

....
    <li><a href="index.py?id=HTML">HTML</a></li>
    <li><a href="index.py?id=CSS">CSS</a></li>
    <li><a href="index.py?id=JavaScript">JavaScript</a></li>
    ....

'''.format(title = pageId))
  • 여기서 cgi는 대체 무엇인가?
    언어와 서버가 공유하는 약속(웹페이지를 띄우기 위한 약속)

Web 부분을 눌렀을 때 id 값이 있냐(있는 것은 내용물들) 없냐(Web은 홈페이지 정면이니까) 하는 조건문

import cgi
form = cgi.FieldStorage()
if 'id' in form:
      pageId = form["id"].value
else:
      pageId = 'Welcome'
  1. 제목 말고 이제 내용물 긁어오기.(파일 읽어와서 치환하기)
  • 먼저 data라는 폴더 하나 만들고 내용이 든 파일을 각각 만든 뒤 파일 불러오는 함수 쓰기
import cgi
form = cgi.FieldStorage()
if 'id' in form:
      pageId = form["id"].value
      description = open('data/'+ pageId, 'r').read()
else:
      pageId = 'Welcome'
      description = 'Hello, Web'
      
      ....
      
        <p>{desc}</p>
</body>
</html>

'''.format(title = pageId, desc = description))

  1. 새로운 목차를 수작업 없이 만들고 싶다면?
    data 폴더 안에 파일만 만들고 바로 List가 작성 되는 것 볼 수 있음
import cgi, os

files = os.listdir('data')
listStr = ''
for item in files:
      listStr = listStr + '<li><a href="index.py?id={name}">{name}</a></li>'.format(name = item)
      ...
      
      <ol>
  {listStr}
  </ol>
  <h2>{title}</h2>
  <p>{desc}</p>
</body>
</html>

'''.format(title = pageId, desc = description, listStr = listStr))
  1. Form : 사용자가 추가할 수 있는 것 만들어보기
  • create.py index.py 복사 해서 만든 뒤
  • 먼저 폼 만들기 준비(보안을 위한 post 방식)
  <a href = "create.py">create</a>
<form action = "process_create.py" method = "post"> 
  <p><input type = "text" name = "title" placeholder = "title"></p>
  <p><textarea rows = "4" name = "description"></textarea></p>
  <p><input type = "submit" placeholder - "description"></p>
</form>

링크에서 파일 작성 뒤 페이지에서 띄우기(리다이렉션)

proccess_create.py

#!/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
import cgi

form = cgi.FieldStorage()
title = form["title"].value
description = form["description"].value

print(title, description)

opened_file = open('data/'+title, 'w')
opened_file.write(description)

print("Location: index.py?id="+title)
print()

  1. update
    (중간 중간 기능 구현을 위해 하는 것)
터미널에
htdocs % sudo chmod a+x update.py 

create.py 복사 후 update.py

<form action = "process_update.py" method = "post"> 
  <input type = "hidden" name = "pageId" value = "{form_default_title}">
  <p><input type = "text" name = "title" placeholder = "title" value ="{form_default_title}"></p>
  <p><textarea rows = "4" name = "description">{form_default_description}</textarea></p>
  <p><input type = "submit" placeholder - "description"></p>
</form>

process_update.py

#!/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
import cgi, os

form = cgi.FieldStorage()
pageId = form["pageId"].value
title = form["title"].value
description = form["description"].value

opened_file = open('data/'+pageId, 'w')
opened_file.write(description)

os.rename('data/'+pageId, 'data/'+title)

print("Location: index.py?id="+title)
print()

이렇게 하면 제목과 내용을 모두 바꿀 수 있는 기능 만들어짐(update 버튼은 필요할 때만 나오게 if문 처리 되어 있음)
index.py

form = cgi.FieldStorage()
if 'id' in form:
      pageId = form["id"].value
      description = open('data/'+ pageId, 'r').read()
      update_link = '<a href = "update.py?id={}" >update</a>'.format(pageId)
else:
      pageId = 'Welcome'
      description = 'Hello, Web'
      update_link = ''

  1. 삭제 기능 만들기
    삭제 또한 바로 되는 것이기 때문에 if 문 안에서 만들어짐
if 'id' in form:
      pageId = form["id"].value
      description = open('data/'+ pageId, 'r').read()
      update_link = '<a href = "update.py?id={}" >update</a>'.format(pageId)
      delete_action = '''
      <form action = "process_delete.py" method = "post">
          <input type="hidden" name = "pageId" value = "{}">
          <input type = "submit" value = "delete">
      </form>
      '''.format(pageId)
else:
      pageId = 'Welcome'
      description = 'Hello, Web'
      update_link = ''
      delete_action = ''
      
      
      ...
      
      
        {update_link}
  {delete_action}
  <h2>{title}</h2>
  <p>{desc}</p>
</body>
</html>

'''.format(title = pageId, desc = description, listStr = listStr, update_link = update_link, delete_action = delete_action))

process_delete.py

#!/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
import cgi, os

form = cgi.FieldStorage()
pageId = form["pageId"].value

os.remove('data/'+pageId)

print("Location: index.py")
print()

delete 버튼이 생성된 것을 누르면 만들어진 것이 지워지고 홈페이지로 돌아감.

여태까지 알아본 모든 내용이 CRUD임.


(만들어진 홈페이지 다듬기 ; 리펙토링 by 함수)

  • 함수라는 수납상자로 담아놓기(def getList())
  • 함수 중복 되는 것들 제거하기(사용자 정의 모듈만들기, view.py를 임포트하기 ; html link 생각하기.)

(보안)

내가 만든 홈페이지의 자바스크립트를 건드려서 사용자를 곤란하게 만드는 것...?->보안 문제 발생

if 'id' in form:
      pageId = form["id"].value
      description = open('data/'+ pageId, 'r').read()
      description = description.replace('<', '&lt;')
      description = description.replace('>', '&gt;')

스크립트 태그를 문자열로 바꾸는 예시


(협업)
Pypi / PIP sanitize 를 집어 넣어서 코드 전체적 정리(전체적으로 넣음.)

(API)
새로 만드는 것 : application
문법 : syntax
프로그램 : 시간에 순서에 따라(프로그래밍)

문법에 따라 시간에 순서에 맞춰 했다 : app과 프로그램은 같은 의미.

그럼 API는? : 앱을 만들기 위해 시간의 순서에 따라 배치한 부품(함수)을 의미, 타인에게 공개해서 함께 사용하는 것.


결론 : 앞으로의 방향성

  • 파이썬과 웹을 연결하기 위해 사용한 것이 이번에는 CGI but 느리다.
  • FastCGI, WSGI를 주로 쓴다.
  • 이걸 직접 쓰긴 어렵다. 그래서 쓰는 도움 프로그램이 웹 프레임워크(django, flask....)
  • 정보를 파일에 저장해왔다. : 그 많은 것을 실시간으로 가져와야 한다면? -> 데이터베이스(많고 빠르게)
  • 검색엔진의 존재 근원, 웹페이지 분석 : 크롤링
profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글