지난 번에 이어서 토네이도(Tornado) 공부를 진행하겠습니다.
이번 포스팅에서는
Request handler and Request argument 에 대해서 공부를 진행합니다.
토네이도 웹 어플리케이션은 URL 또는 URL 패턴을 tornado.web.RequestHandler의 subclass(서브클래스)로 매핑합니다.
이 클래스들은 해당 URL로의 HTTP GET 또는 POST request를 처리하기 위한 get() 또는 post() 메소드를 정의합니다.
지난 시간에 진행했던 기본 테스트 예제를 먼저 확인하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # from : http://www.tornadoweb.org/en/stable/#hello-world # myapp.py import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") def make_app(): return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() | cs |
6번 라인을 확인하면 MainHandler 가 존재합니다.
12번 라인을 확인하면 URL인 '/' 는 MainHandler에 매핑되고 있습니다.
다른 예제를 통해 한번 더 확인하겠습니다.
아래 코드는 URL인 '/'는 MainHandler에, URL 패턴인 '/story/([0-9]+)' 는 StoryHandler 로 매핑하고 있습니다.
정규식(regular expression) 그룹은 Requesthandler 메소드에게 argument로 전달됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import tornado.httpserver import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("You requested the main page") class StoryHandler(tornado.web.RequestHandler): def get(self, story_id): self.write("You requested the story " + story_id) application = tornado.web.Application([ (r"/", MainHandler), (r"/story/([0-9]+)", StoryHandler), ]) if __name__ == "__main__": http_server = tornado.httpserver.HTTPServer(application) http_server.listen(8888) tornado.ioloop.IOLoop.instance().start() | cs |
빨간색 동그라미를 확인하면 MainHandler 매핑되는 '/' 를 확인할 수 있다.
빨간색 동그라미를 확인하면 StoryHandler 매핑되는 '/story/([0-9]+)' 를 확인할 수 있다.
또한 get_argument () 메소드를 사용하면 query string 을 가져와서 POST 바디의 내용을 파싱할 수 있습니다.
코드와 실행결과는 아래와 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import tornado.httpserver import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write('<html><body><form action="/" method="post">' '<input type="text" name="message">' '<input type="submit" value="Submit">' '</form></body></html>') def post(self): self.set_header("Content-Type", "text/plain") self.write("You wrote " + self.get_argument("message")) application = tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": http_server = tornado.httpserver.HTTPServer(application) http_server.listen(8888) tornado.ioloop.IOLoop.instance().start() | cs |
코드의 7~10 라인을 통해 input 칸과 button이 만들어짐을 확인할 수 있다.
input의 이름은 message로 설정되어 있다.
form tag로 묶여있으며 form tag의 내부를 확인하면 post 방식으로 데이터를 보낸다.
따라서 버튼을 누르면 input 에 입력된 값이 post 방식으로 '/' 주소로 넘어가며
그때 넘어가는 데이터의 이름은 message 이다.
12번 라인의 post 함수를 보면 이를 받아 페이지를 구성하는 것을 알 수 있다.
14번 라인에서 message 라는 argument를 얻어서
You wrote ~ 을 만들어 낸다.
클라이언트에 에러 response ( 예를들면 403 Unauthorized 같은 ) 를 보내려면
tornado.web.HTTPError exception을 raise해주면 됩니다.
1 2 | if not self.user_is_logged_in(): raise tornado.web.HTTPError(403) | cs |
request handler에서 현재 request 오브젝트를 self.request로 access할 수 있습니다.
HTTPRequest 오브젝트는 여러가지 유용한 attribute를 포함하고 있습니다.
▶ arguments - GET 과 POST의 전체 argument
▶ files - (multipart/form-data POST request를 통한) 모든 업로드 된 파일들
▶ path - request 패스 (URL 에서 '?' 앞쪽 전체)
▶ headers - request 헤더
모든 attribute 목록은 httpserver의 HTTPRequest 클래스 정의를 확인하면 됩니다.
이상으로 Tornado에서 Request handler and request argument 에 대한 포스팅을 마치도록 하겠습니다.
궁금한 점이 있거나 추가적인 도움을 주고싶으신 분이 있다면
댓글이나 doorBW@outlook.com 을 통해 메일주세요!