본문 바로가기
프로그래밍 놀이터/Script(Python)

[Django] 파이썬 웹 프로그래밍 - 파이썬 웹 표준 라이브러리

by 돼지왕 왕돼지 2016. 12. 8.
반응형

 [Django] 파이썬 웹 프로그래밍 - 파이썬 웹 표준 라이브러리


200 ok, 404 not found, 755, add_data, add_header, add_password, application, application_name(environ, basehttprequesthandler, basehttpserver, baserequesthandler, body, build_opener, Call, cgi, cgi 단점, cgi 스크립트, cgi-bin, cgihttpserver, cgitb, CLOSE, data, Def, default opener, Django, do_get, do_head, do_post, endheaders, environ, fast cgi, fieldstorage, file scheme, flask, form = cgi.FieldStorage(), form.getValue, fragment, From, Get, getresponse, getvalue, handler, Head, header, Headers, host:port, HTTP, http package, http 환경변수, http.cient, http.cookie, http.cookiejar, http.server, httpbasicauthhandler, httpconnection, httpcookieprocessor, httplib 모듈, httprequest, HttpResponse, httpserver, HTTP_HOST, HTTP_USER_AGENT, import, install_opener, ip, iterable, local file, M, Method, module, netloc, Open, opener.open, params, ParseResult, parse_qs, Path, port, Post, proxybasicauthhandler, proxyhandler, putheader, query, Quote, Read, reason, request, request class, response, Return, scheme, server_protocol, serve_forever, simplehttprequesthandler, simplehttpserver, sned, start_response, start_response), status, stdout, streamrequesthandler, tcpserver, timeout, tutorial, unquote, url, URL encoding, urlencode, urljoin, urllib, urllib package, urllib2, urllib2 모듈 예제, urlopen, urlparse 모듈, urlretrive, urlsplit, user:password@host:port, web server gateway interface, werkzeug, wfile, wsfiref, wsgi, wsgi.py, wsgiref, wsgiref.simple_Server, wsgirequesthandler, wsgiscriptalias, wsgiserver, xxxhttpserver, [Django] 파이썬 웹 프로그래밍 - 파이썬 웹 표준 라이브러리, __main__, __name__, 간단한 웹 서버, 개발자, 데이터, 독립적인 웹 앱, 라이브러리 모듈, 리스트, 메소드, 모듈, 바디, 벡자이크, 변경, 분해, 뷰 처리, 상세 정보, 서버용, 쓰레드 처리 방식, 앱 함수, 에러, 엑세스 모드, 연결 객체 생성, 연결 닫기, 오프너, 외부 데몬 프로세스 방식, 요청 보내기, 웹 라이브러리 구성, 웹 서버, 웹 서버 게이트웨이 인터페이스, 웹 서버 라이브러리, 웹 서버 프로그래밍, 웹 앱, 웹 클라이언트, 웹 클라이언트 프로그래밍, 웹 프레임워크, 웹 프로그래밍, 위임, 유사 파일 객체, 응답, 응답 객체 생성, 응답 데이터 읽기, 응답 메시지, 응답 바디, 응답 헤더, 인증 데이터, 장고, 저수준 api, 저수준 http 라이브러리, 제네레이터, 조립, 처리 위임, 쿠키 데이터, 클라이언트용, 클래스, 타이머, 파라미터 전달, 파라미터 처리, 파이썬, 패키지, 표준 라이브러리, 프록시 서버 요청, 핸들러, 핸들러 객체, 헤더, 헤더 변경, 헤더 추가, 환경 변수

-
책을 읽으며 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 서버 동작 확인







반응형

댓글