반응형
[Django] 파이썬 웹 프로그래밍 - 파이썬 웹 표준 라이브러리 |
-
책을 읽으며 Remind 하는 내용, 핵심 내용, 모르던 내용을 정리한 것입니다. 예문 및 자세한 설명은 책을 구매하여 보세요~
-
파이썬을 설치하면 기본적으로 같이 설치되는 표준 라이브러리가 있는데, 크게 웹 클라이언트 프로그래밍이냐 웹 서버 프로그래밍이냐에 따라 사용하는 라이브러리 모듈이 달라진다.
< 2.1. 웹 라이브러리 구성 >
-
urllib 패키지에는 웹 클라이언트를 작성하는 데 사용되는 모듈들이 있으며, 가장 빈번하게 사용하는 모듈이다.
http 패키지는 크게 서버용과 클라이언트용 라이브러리로 나누어 모듈을 담고 있고, urllib 에 비해 저수준의 API 를 제공한다.
-
서버 프로그래밍에서는 http.cookie, http.server 를 주로 사용하고,
클라리언트 프로그래밍에서는 urllib 과 http.client, http.cookiejar 가 주로 사용된다.
-
장고와 같은 웹 프레임워크를 사용하여 웹 서버를 개발한다면 http.cookie 나 http.server 모듈은 거의 사용할 일이 없다.
웹 프레임워크는 사용자 프로그램과 저수준의 http 라이브러리 중간에 위치하여 웹 서버 개발을 좀 더 편리하게 해주면서, 표준 라이브러리의 기능을 확장해주는 역할을 하고 있기 때문이다.
< 2.2. 웹 클라이언트 라이브러리 >
-
URL 의 분해, 조립, 변경 등을 처리하는 함수를 제공한다.
-
urlparse() 는 URL 을 파싱한 결과로 ParseResult 인스턴스를 반환한다.
scheme, netloc( user:password@host:port 또는 host:port 형식 ), path, params, query, fragment 등의 속성이 있다.
-
urlsplit(), urljoin(), parse_qs() 함수 등이 있다.
-
주어진 URL 에서 데이터를 가져오는 기본 기능을 제공한다.
-
urlopen(url, data=None, [timeout]) 은 지정한 URL 로 연결하여 유사 파일 객체를 반환한다.
url 인자는 문자열이나 Request 클래스가 올 수 있다.
Request 클래스는 헤더의 추가, 변경이 필요한 경우에 사용한다.
url 에 file 스킴을 지정하면 로컬 파일을 열 수 있다.
디폴트 요청 방식은 GET 이고, POST 로 보내고 싶으면 data 인자에 URL Encoding 된 질의 문자열을 지정해주면 된다.
( data = “query=python” )
-
Request 는 add_header(), add_data() 메소드를 통해 헤더와 데이터를 추가하여 웹 서버 요청을 할 수 있다.
ex)
req = urllib2.Request(“http://www.example.com”)
req.add_header(“Content-Type”, “text/plain”)
req.add_data(“query=python”) # POST 로 자동 전환된다.
f = urllib2.urlopen(req)
print f.read(500)
-
인증 데이터나 쿠키 데이터를 추가하여 요청을 보내거나, 프록시 서버로 요청을 보내는 등의 고급기능을 위해서는
각 기능에 맞는 핸들러 객체를 정의하고, build_opener() 함수를 이용해 핸들러를 오프너로 등록해야 한다.
urlopen() 함수로 이 오프너를 열기 위해서는 install_opener() 함수를 사용하여 디폴트 오프너로 설정하면 된다.
ex)
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm=‘PDQ Application’, uri=‘https://mahler:8092/site-updates.py', user=‘klem’, passwd=‘kadidd!ehopper’)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
u = urllib2.urlopen(“http://example.com/login.html”)
ex2)
cookie_handler = urllib2.HTTPCookieProcessor()
opener = urllib2.build_opener(cookie_handler)
urllib2.install_opener(opener)
u = urllib2.urlopen(“http://www.example.com/login.html”)
ex3)
proxy_handler = urllib2.ProxyHandler({“http”:”http://www.example.com:3128/“})
proxy_auth_handler = urllib2.ProxyBasicAuthHandler()
proxy_auth_handler.add_password(“realm”, “host”, “username”, “password”)
opener = urllib2.build_opener(proxy_handler, proxy_auth_handler)
u = opener.open(“http://www.example.com/login.html”) # install_opener, urlopen 대신 사용할 수 있다.
-
urlretrive(), quote(), unquote() urlencode() 등의 함수 등이 있다.
* 2.2.3. urllib2 모듈 예제
* 2.2.4. httplib 모듈
-
대부분의 웹 클라 프로그램은 urllib2 모듈에 정의된 기능만으로 가능하다.
그러나 GET, POST 방식 이외의 요청을 보내거나, 요청 헤더와 바디 사이에 타이머를 두어 시간 지연시키는 등의 처리는 어렵기 때문에 httplib 모듈을 사용해야 한다.
-
httplib 모듈 사용시 코딩 순서는 아래와 같다.
1. 연결 객체 생성 / conn = httplib.HTTPConnection(“www.example.com”)
2. 요청 보내기 / conn.request(“GET”, “/index.html”)
3. 응답 객체 생성 / response = conn.getresponse()
4. 응답 데이터 읽기 / data = response.read()
5. 연결 닫기 / conn.close()
ex)
params = urllib2.urlencode({‘@number’ : 12524, ‘@type’ : ‘issue’, ‘@action’ : ‘show’})
headers = {“Content-type”:”application/x-www-form-urlencoded”, “Accept”:”text/plain”}
conn = httplib.HTTPConnection(“bugs.python.org”)
conn.request(“POST”, “”, param, headers) # request(method, url, body, headers)
response = conn.getresponse()
print (response.status, response.reason)
data = response.read()
print (data)
conn.close()
-
httplib 모듈에는 putheader(), endheaders(), send() 등의 메소드가 더 있다.
< 2.3. 웹 서버 라이브러리 >
* 2.3.1. 간단한 웹 서버
-
respone 로 Hello World 를 주는 서버 예제는 아래와 같다.
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.wfile.write(“Hello World”)
if __name__ == ‘__main__’:
server = HTTPServer((“”, 8888), MyHandler)
server.serve_forever()
-
웹 서버를 만드는 가장 기본적인 방법은 아래와 같다.
1. BaseHTTPServer 모듈을 import 한다.
2. BaseHTTPRequestHandler 를 상속받아, 원하는 로직으로 핸들러 클래스를 구현한다.
3. 서버의 IP, PORT 및 핸들러 클래스를 인자로 하여 HTTPServer 객체를 생성한다.
4. HTTPServer 객체의 serve_forever() 메소드를 호출한다.
-
BaseHTTPServer 는 기반 클래스로 HTTP 프로토콜을 처리한다.
SimpleHTTPServer 는 GET 과 HEAD 메소드 처리 가능하다.
CGIHTTPServer 는 POST 와 CGI 처리 가능하다.
* 2.3.2. BaseHTTPServer 모듈
* 2.3.3. SimpleHTTPServer 모듈
-
SimpleHTTPServer 모듈에는 간단한 핸들러(SimpleHTTPRequestHandler 클래스)가 미리 구현되어 있어 필요할 떄 즉시 웹 서버를 실행할 수 있다.
이 핸들러에는 do_GET(), do_HEAD() 메소드가 정의되어 있다.
POST 등 그 외의 HTTP 메소드는 처리할 수 없다.
$ python -m SimpleHTTPServer 8888 # test 함수를 돌린다, -m 은 파일 이름을 module 처럼 돌린다.
* 2.3.4. CGIHTTPServer 모듈
-
CGIHTTPRequestHandler 가 미리 구현되어 있어 필요할 때 즉시 웹 서버를 실행할 수 있다.
이 핸들러에는 do_POST() 메소드가 정의되어 있다.
$ python -m CGIHTTPServer 8888 # test 함수를 돌린다.
-
CGI 스크립트는 cgi-bin 디렉토리 하위에 위치해야 하며, 파일의 액세스 모드도 755 여야 한다.
질의 문자열 접근을 위해서는 form = cgi.FieldStorage() 로 instance 를 생성하고,
form.getvalue(‘language’) 와 같은 방식으로 값을 가져올 수 있다.
* 2.3.5. xxxHTTPServer 모듈 간의 관계
-
모든 웹 서버는 BaseHTTPServer 모듈의 HTTPServer 클래스를 사용하여 작성하고,
웹 서버에 사용되는 핸들러는 BaseHTTPRequestHandler 를 상속받아 작성한다.
SimpleHTTPServer 와 CGIHTTPServer 도 매한가지다.
-
TCPServer 를 상속한 HTTPServer
BaseRequestHandler 를 상속한 StreamRequestHandler. 이를 상속한 BaseHTTPRequestHandler. 이를 상속한 SimpleHTTPRequestHandler. 이를 상속한 CGIHTTPRequestHandler.
TCPServer, BaseRequestHandler, StreamRequestHandler 는 SocketServer 모듈에 포함된다.
SimpleHTTPServer 모듈과 CGIHTTPServer 모듈은 HTTPServer 를 import 해서 사용한다.
-
각 모듈에는 해당 HTTPServer 별도 코딩 없이 기동할 수 있도록 test() 함수를 정의하고 있다.
< 2.4. CGI/WSGI 라이브러리 >
-
파이썬에서는 WSGI (Web Server Gateway Interface) 규격을 정의하고,
파이썬 앱을 실행하고자 하는 웹 서버는 이 규격을 준수해야 한다.
WSGI 는 웹 서버와 웹 앱을 연결해주는 규격이다.
-
WSGI 규격을 구현하기 위해 파이썬 표준 라이브러리에는 cgi 모듈과 wsgiref 모듈이 같이 존재한다.
CGI 기술은 이미 사라진 기술이지만, cgi 모듈의 라이브러리는 WSGI 기술에 여전히 사용되고 있다.
* 2.4.1. CGI 관련 모듈
-
CGI 모듈에는 요청에 포함된 파라미터를 처리하기 위한 FieldStorage 클래스를 정의하고 있고,
CGI 앱이 실행 중 에러가 발생하는 경우, 에러에 대한 상세 정보를 브라우저에 표시해주는 cgitb 모듈도 있다.
* 2.4.2. WSGI 개요
-
CGI 단점 해결을 위한 방법으로 Fast CGI, 쓰레드 처리 방식, 외부 데몬 프로세스 방식 등 여러 가지가 사용되고 있다.
이런 고려사항이 웹 앱을 작성하는 개발자에게 주어지면 개발이 너무 어려워진다.
웹 서버와 웹 앱 중간에서 이런 까다로운 처리를 해주는 것이 장고와 같은 웹 프레임워크이다.
cf) Fast CGI 는 매 요청마다 Process 를 생성하지 않고, 단일 Process 에서 여러 요청을 처리하는 방식. Process 는 CGI Server 가 갖는다.
-
웹 앱을 한번만 작성하면 다양한 웹 서버에서 동작할 수 있도록,
즉 웹 서버에 독립적인 웹 앱을 작성할 수 있도록 웹 서버와 웹 앱 간의 연동규격을 정의한 것이 WSGI 이다.
* 2.4.3. WSGI 서버의 앱 처리 과정
-
웹 서버에서 클라이언트의 요청을 받아 WSGI 서버로 처리를 위임하고,
WSGI 서버는 앱을 실행하여 그 결과를 웹 서버에게 되돌려주면,
웹 서버는 클라이언트에게 응답한다.
-
Request
-> 웹서버에서
Request URL 분석
WSGIScriptAlias 에 정의된 URL 이면, WSGI 서버에 처리 위임
-> 파라미터 전달
-> WSGI 서버
WSGIScriptAlias 에 정의된 wsgi.py 실행
application(environ, start_reponse) 함수 호출
-> Call
-> Application
environ 환경 변수 처리
뷰 처리, HTTPRequest 객체 생성
start_response() 함수 호출
return HTTPResponse
-> Return
-> WSGI 서버
표준 출력(stdout)에 결과 출력
-> 처리결과
-> Response
-
WSGI 규격에 따라 앱 개발할 때 중요한 사항은 아래 세 가지이다.
1. 개발이 필요한 앱 함수 또는 클래스의 메소드로 정의하고, 앱 함수의 인자는 다음과 같이 정의한다.
def application_name(environ, start_response) :
environ 은 웹 프레임워크에 이미 정의되어 있으며, HTTP_HOST, HTTP_USER_AGENT, SERVER_PROTOCOL 과같은 HTTP 환경 변수를 포함한다.
start_response 는 앱 내에서 응답을 시작하기 위해 반드시 호출해야 하는 함수이다.
2. start_response 함수의 인자 역시 다음과 같이 정해져 있으며, 따라야 한다.
start_response(status, headers)
status 는 응답 코드 및 응답 메시지를 지정한다. ( 200 OK, 404 Not Found 등 )
headers 는 응답 헤더를 포함한다.
3. 앱 함수의 리턴값은 응답 바디에 해당하는 내용으로, 리스트나 제너레이터와 같은 iterable 타입이어야 한다.
* 2.4.4. wsgiref.simple_server 모듈
-
표준 라이브러리에 웹 프레임워크 개발자가 웹 서버와의 연동 기능을 개발할 수 있도록 wsgiref 패키지의 하위 모듈로 wsgiref.simple_server 모듈을 제공하고 있다.
이 모듈은 WSGI 스펙을 준수하는 웹 서버에 대한 참조 서버, 즉 개발자에게 참고가 될 수 있도록 미리 만들어 놓은 WSGIServer 클래스와 WSGIRequestHandler 클래스를 정의하고 있다.
그러나 모든 웹 프레임워크가 wsgiref 패키지를 사용하는 것은 아니다.
wsgiref 패키지를 사용하지 않아도, WSGI 스펙을 준수하는 자신만의 웹 프레임워크 또는 WSGI 서버를 만들면 되기 때문이다.
Flask 웹 프레임워크에서 사용하는 벡자이크(Werkzeug)가 wsgiref 를 사용하지 않는 WSGI 서버의 예다.
-
ex)
def my_app(environ, start_response):
status = “200 OK"
headers = [ (‘Content-Type’, ‘text/plain’) ]
start_response(status, headers )
return [“This is a sample WSGI Application.”]
if __name__ == ‘__main__’:
from wsgiref.simple_server import make_server
server = make_server(‘’, 8888, my_app)
server.serve_forever()
# simpel_server 모듈의 Server 는 HTTPServer 를 상속한 WSGIServer 이고,
# my_app 대신 BaseHTTPRequestHandler 를 상속한 WSGIRequestHandler 를 사용해도 된다.
cf) if __name__ == '__main__':
Python 은 C 나 Java 의 main 함수에 매칭되는 것이 없다.
그래서 python main.py 를 수행하면 main.py 의 들여쓰기 하지 않은 모든 코드(level 0코드)를 실행하며, 이 때만 __name__ 이라는 내장변수에 '__main__' 이라는 녀석이 할당된다.
* 2.4.5. WSGI 서버 동작 확인
반응형
'프로그래밍 놀이터 > Script(Python)' 카테고리의 다른 글
[Django] 파이썬 웹 프로그래밍 - Django 의 핵심 기능 #1 (0) | 2016.12.13 |
---|---|
[Django] 파이썬 웹 프로그래밍 - Django 웹 프레임워크 #2 (0) | 2016.12.12 |
[Django] 파이썬 웹 프로그래밍 - Django 웹 프레임워크 #1 (0) | 2016.12.09 |
[Django] 파이썬 웹 프로그래밍 - 웹 프로그래밍의 이해 (0) | 2016.12.06 |
[python3] 뇌를 자극하는 파이썬 - 코딩을 배우기 전에 읽는 컴퓨터 구조론 (0) | 2016.09.27 |
댓글