{"id":212,"date":"2017-07-08T23:03:20","date_gmt":"2017-07-08T15:03:20","guid":{"rendered":"http:\/\/zkeeer.space\/?p=212"},"modified":"2017-07-20T00:45:40","modified_gmt":"2017-07-19T16:45:40","slug":"%e3%80%90%e7%bf%bb%e8%af%91%e3%80%91%e4%b8%80%e6%ad%a5%e6%ad%a5%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaweb%e6%9c%8d%e5%8a%a1%e5%99%a8-part-2","status":"publish","type":"post","link":"http:\/\/zkeeer.space\/?p=212","title":{"rendered":"\u3010\u7ffb\u8bd1\u3011\u4e00\u6b65\u6b65\u5f00\u53d1\u4e00\u4e2aWeb\u670d\u52a1\u5668.Part 2."},"content":{"rendered":"<blockquote><p>\u539f\u6587\u94fe\u63a5\uff1a<a class=\" wrap external\" href=\"https:\/\/ruslanspivak.com\/lsbaws-part2\/\" target=\"_blank\" rel=\"nofollow noreferrer noopener\">Let\u2019s Build A Web Server. Part 2.<i class=\"icon-external\"><\/i><\/a><br \/>\n\u8bd1\u6587\u94fe\u63a5\uff1a<a class=\" wrap external\" href=\"http:\/\/zkeeer.space\/?p=212\" target=\"_blank\" rel=\"nofollow noreferrer noopener\">\u3010\u7ffb\u8bd1\u3011\u4e00\u6b65\u6b65\u5f00\u53d1\u6253\u9020\u4e00\u4e2aWeb\u670d\u52a1\u5668.Part 2.<i class=\"icon-external\"><\/i><\/a><br \/>\n\u672c\u6587\u4ee3\u7801\u57fa\u4e8epython2.x<\/p>\n<p>\u53d1\u73b0\u9519\u8bef\u8bf7\u5728\u8bc4\u8bba\u533a\u6307\u51fa\uff0c\u591a\u8c22<\/p>\n<p>\u672c\u7cfb\u5217\u5176\u4ed6\u6587\u7ae0\uff1a<br \/>\n<a class=\" wrap external\" href=\"http:\/\/zkeeer.space\/?p=192\" target=\"_blank\" rel=\"nofollow noreferrer noopener\">\u3010\u7ffb\u8bd1\u3011\u4e00\u6b65\u6b65\u5f00\u53d1\u4e00\u4e2aWeb\u670d\u52a1\u5668.Part 1.<i class=\"icon-external\"><\/i><\/a><br \/>\n<a class=\" wrap external\" href=\"http:\/\/zkeeer.space\/?p=212\" target=\"_blank\" rel=\"nofollow noreferrer noopener\">\u3010\u7ffb\u8bd1\u3011\u4e00\u6b65\u6b65\u5f00\u53d1\u4e00\u4e2aWeb\u670d\u52a1\u5668.Part 2.<i class=\"icon-external\"><\/i><\/a><br \/>\n<a class=\" wrap external\" href=\"http:\/\/zkeeer.space\/?p=246\" target=\"_blank\" rel=\"nofollow noreferrer noopener\">\u3010\u7ffb\u8bd1\u3011\u4e00\u6b65\u6b65\u5f00\u53d1\u4e00\u4e2aWeb\u670d\u52a1\u5668.Part 3.<\/a><\/p><\/blockquote>\n<p>\u8bb0\u5f97\uff0c\u6211\u5728<a href=\"http:\/\/zkeeer.space\/?p=192\">Part 1 <\/a>\u4e2d\u7559\u4e86\u4e2a\u4f5c\u4e1a\u9898\uff1a\u4e0d\u6539\u53d8\u670d\u52a1\u5668\u4ee3\u7801\u7684\u60c5\u51b5\u4e0b\uff0c\u600e\u6837\u5728\u4f60\u521a\u5b8c\u6210\u7684\u670d\u52a1\u5668\u4e0a\u8fd0\u884c\u4e00\u4e2aDjango\u3001Flask\u3001Pyramid\u5e94\u7528\uff0c\u9002\u5e94\u4e0d\u540c\u7684web\u6846\u67b6\uff1f \u9605\u8bfb\u5b8c\u8fd9\u7bc7\u6587\u7ae0\u4f60\u5c31\u80fd\u5f97\u5230\u7b54\u6848\u3002<\/p>\n<p>\u5728\u8fc7\u53bb\uff0c\u4f60\u9009\u62e9\u4e00\u4e2apython web\u6846\u67b6\u5f80\u5f80\u53d7\u9650\u4e8e\u53ef\u7528\u7684web\u670d\u52a1\u5668\u7684\u9009\u62e9\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002\u5982\u679c\u4f60\u9009\u62e9\u7684\u6846\u67b6\u548c\u4f60\u7684\u670d\u52a1\u5668\u6070\u597d\u80fd\u5728\u4e00\u8d77\u5de5\u4f5c\uff0c\u8fd9\u65f6\u5019\u4f60\u5c31\u4e50\u4e86\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-213 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_before_wsgi-1024x671.png\" alt=\"\" width=\"1024\" height=\"671\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_before_wsgi.png 1024w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_before_wsgi-300x197.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_before_wsgi-768x503.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>\u4f60\u6216\u8bb8\u8981\u9762\u5bf9\uff08\u6216\u8005\u5df2\u7ecf\u9047\u5230\u4e86\uff09\u8fd9\u6837\u4e00\u4e2a\u95ee\u9898\uff1a\u5f53\u4f60\u60f3\u8981\u628a\u4e00\u4e2a\u6846\u67b6\u548c\u4e00\u4e2a\u670d\u52a1\u5668\u7ed3\u5408\u5728\u4e00\u8d77\u65f6\uff0c\u4f60\u53d1\u73b0\u5b83\u4eec\u5e76\u4e0d\u80fd\u5f88\u597d\u7684\u7ed3\u5408\u5728\u4e00\u8d77\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-214 size-full\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_after_wsgi.png\" alt=\"\" width=\"968\" height=\"768\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_after_wsgi.png 968w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_after_wsgi-300x238.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_after_wsgi-768x609.png 768w\" sizes=\"(max-width: 968px) 100vw, 968px\" \/><\/p>\n<p>\u4ece\u6839\u672c\u4e0a\u6765\u8bb2\uff0c\u4f60\u4e0d\u5f97\u4e0d\u7528\u90a3\u4e9b\u80fd\u4e00\u8d77\u5de5\u4f5c\u7684\u5374\u4e0d\u662f\u4f60\u60f3\u7528\u7684\u6846\u67b6\u548c\u670d\u52a1\u5668\u3002<\/p>\n<p>\u6240\u4ee5\uff0c\u5728\u4e0d\u6539\u53d8web\u670d\u52a1\u5668\u548cweb\u6846\u67b6\u7684\u60c5\u51b5\u4e0b\uff0c\u4f60\u8981\u600e\u6837\u624d\u80fd\u786e\u4fdd\u4f60\u7684web\u670d\u52a1\u5668\u80fd\u591f\u9002\u5e94\u4e0d\u540c\u7684web\u6846\u67b6\uff1f\u7b54\u6848\u5c31\u662fPython \u670d\u52a1\u5668\u7f51\u5173\u63a5\u53e3\uff08Web Server Gateway Interface\uff0c \u7f29\u5199\u4e3a<a href=\"http:\/\/baike.baidu.com\/link?url=W2adNpi0RUeClrebEOgo5Cc3Vc7_dCsYV5B-5XGJbpg3nCibShcaiy5kc3Uqg28TNClN1X1sBdPwe1pULBnj_K\">WSGI<\/a>\uff0c\u8bfb\u4f5c<em>wizgy<\/em>\uff09<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-215 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_idea-1024x536.png\" alt=\"\" width=\"1024\" height=\"536\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_idea.png 1024w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_idea-300x157.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_idea-768x402.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>WSGI \u5141\u8bb8\u5f00\u53d1\u8005\u5728web\u6846\u67b6\u548cweb\u670d\u52a1\u5668\u4e0a\u505a\u51fa\u4e0d\u540c\u9009\u62e9\u3002\u4f60\u53ef\u4ee5\u6839\u636e\u4f60\u7684\u9700\u8981\u642d\u914d\u4e0d\u540c\u7684web\u6846\u67b6\u548cweb\u670d\u52a1\u5668\u4e86\u3002\u53ef\u4ee5\u4f7f\u7528Django\u3001Flask\u6216\u8005Pyramid\uff0c\u4e3e\u4e2a\u6817\u5b50\uff0cGunicorn\u6216\u8005Nginx\/uWSGI\u53c8\u6216\u8005Waitress\u3002\u5b83\u505a\u5230\u4e86\u771f\u6b63\u7684\u6df7\u5408\u548c\u642d\u914d\uff0c\u540c\u65f6\u652f\u6301\u670d\u52a1\u5668\u548c\u6846\u67b6\uff0cWSGI\u8c22\u5929\u8c22\u5730\u4f60\u6765\u4e86\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-216 size-full\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interop.png\" alt=\"\" width=\"906\" height=\"768\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interop.png 906w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interop-300x254.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interop-768x651.png 768w\" sizes=\"(max-width: 906px) 100vw, 906px\" \/><\/p>\n<p>\u6240\u4ee5\uff0cWSGI\u5c31\u662f\u6211\u4e00\u904d\u53c8\u4e00\u904d\u95ee\u4f60\u7684\u90a3\u4e2a\u95ee\u9898\u7684\u7b54\u6848\u3002\u4f60\u7684web\u670d\u52a1\u5668\u5fc5\u987b\u5b9e\u73b0\u4e00\u4e2aWSGI\u7684\u670d\u52a1\u5668\u63a5\u53e3\uff0c\u5f53\u4e0b\u7684Python Web\u6846\u67b6\u90fd\u5df2\u7ecf\u5b9e\u73b0\u4e86WSGI\u7684\u6846\u67b6\u63a5\u53e3\u3002\u5982\u6b64\u4e00\u6765\uff0c\u4e0d\u7528\u4fee\u6539\u4efb\u4f55\u4ee3\u7801\uff0c\u4f60\u7684web\u670d\u52a1\u5668\u53ef\u4ee5\u4f7f\u7528\u63a5\u53e3\u9002\u7528\u4e8e\u4e00\u4e2a\u7279\u5b9a\u7684web\u6846\u67b6\u3002<\/p>\n<p>\u73b0\u5728\u4f60\u5df2\u7ecf\u77e5\u9053\u4e86WSGI\u540c\u65f6\u652f\u6301\u670d\u52a1\u5668\u548c\u6846\u67b6\u6765\u6ee1\u8db3\u4f60\u4e0d\u540c\u9009\u62e9\u7684\u9700\u6c42\uff0c\u8fd9\u4e5f\u4f7f\u5f97\u670d\u52a1\u5668\u548c\u6846\u67b6\u7684\u5f00\u53d1\u8005\u4eec\u6536\u76ca\uff0c\u5b83\u4eec\u80fd\u4e13\u6ce8\u4e8e\u4ed6\u4eec\u64c5\u957f\u7684\u9886\u57df\u800c\u4e0d\u5fc5\u6d89\u8db3\u5bf9\u65b9\u7684\u9886\u57df\u3002\u5176\u4ed6\u8bed\u8a00\u4e5f\u6709\u7c7b\u4f3c\u7684\u63a5\u53e3\uff0c\u53c8\u4e3e\u4e2a\u6817\u5b50\uff1aJava\u6709Servlet API\u3001Ruby\u6709Rack\u3002<\/p>\n<p>\u8fd9\u4e9b\u90fd\u633a\u4e0d\u9519\u7684\uff08\u4f60\u5fc3\u91cc\u6216\u8bb8\u6b63\u5600\u5495\uff1a\u522b\u903c\u903c\u4e86\uff0c\u4e0a\u4ee3\u7801\uff01\uff09\u3002OK\uff0c\u8fd9\u4e0b\u9762\u662f\u4e00\u4e2a\u6700\u7b80\u5355\u7684WSGI\u670d\u52a1\u5668\u7684\u5b9e\u73b0\uff1a<\/p>\n<pre><span class=\"c1\"># Tested with Python 2.7.9, Linux &amp; Mac OS X<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">socket<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">StringIO<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">sys<\/span>\r\n\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">WSGIServer<\/span><span class=\"p\">(<\/span><span class=\"nb\">object<\/span><span class=\"p\">):<\/span>\r\n\r\n    <span class=\"n\">address_family<\/span> <span class=\"o\">=<\/span> <span class=\"n\">socket<\/span><span class=\"o\">.<\/span><span class=\"n\">AF_INET<\/span>\r\n    <span class=\"n\">socket_type<\/span> <span class=\"o\">=<\/span> <span class=\"n\">socket<\/span><span class=\"o\">.<\/span><span class=\"n\">SOCK_STREAM<\/span>\r\n    <span class=\"n\">request_queue_size<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"fm\">__init__<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">server_address<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"c1\"># Create a listening socket<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">listen_socket<\/span> <span class=\"o\">=<\/span> <span class=\"n\">listen_socket<\/span> <span class=\"o\">=<\/span> <span class=\"n\">socket<\/span><span class=\"o\">.<\/span><span class=\"n\">socket<\/span><span class=\"p\">(<\/span>\r\n            <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">address_family<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">socket_type<\/span>\r\n        <span class=\"p\">)<\/span>\r\n        <span class=\"c1\"># Allow to reuse the same address<\/span>\r\n        <span class=\"n\">listen_socket<\/span><span class=\"o\">.<\/span><span class=\"n\">setsockopt<\/span><span class=\"p\">(<\/span><span class=\"n\">socket<\/span><span class=\"o\">.<\/span><span class=\"n\">SOL_SOCKET<\/span><span class=\"p\">,<\/span> <span class=\"n\">socket<\/span><span class=\"o\">.<\/span><span class=\"n\">SO_REUSEADDR<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"c1\"># Bind<\/span>\r\n        <span class=\"n\">listen_socket<\/span><span class=\"o\">.<\/span><span class=\"n\">bind<\/span><span class=\"p\">(<\/span><span class=\"n\">server_address<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"c1\"># Activate<\/span>\r\n        <span class=\"n\">listen_socket<\/span><span class=\"o\">.<\/span><span class=\"n\">listen<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">request_queue_size<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"c1\"># Get server host name and port<\/span>\r\n        <span class=\"n\">host<\/span><span class=\"p\">,<\/span> <span class=\"n\">port<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">listen_socket<\/span><span class=\"o\">.<\/span><span class=\"n\">getsockname<\/span><span class=\"p\">()[:<\/span><span class=\"mi\">2<\/span><span class=\"p\">]<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">server_name<\/span> <span class=\"o\">=<\/span> <span class=\"n\">socket<\/span><span class=\"o\">.<\/span><span class=\"n\">getfqdn<\/span><span class=\"p\">(<\/span><span class=\"n\">host<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">server_port<\/span> <span class=\"o\">=<\/span> <span class=\"n\">port<\/span>\r\n        <span class=\"c1\"># Return headers set by Web framework\/Web application<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">headers_set<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">set_app<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">application<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">application<\/span> <span class=\"o\">=<\/span> <span class=\"n\">application<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">serve_forever<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">listen_socket<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">listen_socket<\/span>\r\n        <span class=\"k\">while<\/span> <span class=\"bp\">True<\/span><span class=\"p\">:<\/span>\r\n            <span class=\"c1\"># New client connection<\/span>\r\n            <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">client_connection<\/span><span class=\"p\">,<\/span> <span class=\"n\">client_address<\/span> <span class=\"o\">=<\/span> <span class=\"n\">listen_socket<\/span><span class=\"o\">.<\/span><span class=\"n\">accept<\/span><span class=\"p\">()<\/span>\r\n            <span class=\"c1\"># Handle one request and close the client connection. Then<\/span>\r\n            <span class=\"c1\"># loop over to wait for another client connection<\/span>\r\n            <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">handle_one_request<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">handle_one_request<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">request_data<\/span> <span class=\"o\">=<\/span> <span class=\"n\">request_data<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">client_connection<\/span><span class=\"o\">.<\/span><span class=\"n\">recv<\/span><span class=\"p\">(<\/span><span class=\"mi\">1024<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"c1\"># Print formatted request data a la 'curl -v'<\/span>\r\n        <span class=\"k\">print<\/span><span class=\"p\">(<\/span><span class=\"s1\">''<\/span><span class=\"o\">.<\/span><span class=\"n\">join<\/span><span class=\"p\">(<\/span>\r\n            <span class=\"s1\">'&lt; {line}<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"o\">.<\/span><span class=\"n\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">line<\/span><span class=\"o\">=<\/span><span class=\"n\">line<\/span><span class=\"p\">)<\/span>\r\n            <span class=\"k\">for<\/span> <span class=\"n\">line<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">request_data<\/span><span class=\"o\">.<\/span><span class=\"n\">splitlines<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"p\">))<\/span>\r\n\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">parse_request<\/span><span class=\"p\">(<\/span><span class=\"n\">request_data<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"c1\"># Construct environment dictionary using request data<\/span>\r\n        <span class=\"n\">env<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">get_environ<\/span><span class=\"p\">()<\/span>\r\n\r\n        <span class=\"c1\"># It's time to call our application callable and get<\/span>\r\n        <span class=\"c1\"># back a result that will become HTTP response body<\/span>\r\n        <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">application<\/span><span class=\"p\">(<\/span><span class=\"n\">env<\/span><span class=\"p\">,<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">start_response<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"c1\"># Construct a response and send it back to the client<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">finish_response<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">parse_request<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">text<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">request_line<\/span> <span class=\"o\">=<\/span> <span class=\"n\">text<\/span><span class=\"o\">.<\/span><span class=\"n\">splitlines<\/span><span class=\"p\">()[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\r\n        <span class=\"n\">request_line<\/span> <span class=\"o\">=<\/span> <span class=\"n\">request_line<\/span><span class=\"o\">.<\/span><span class=\"n\">rstrip<\/span><span class=\"p\">(<\/span><span class=\"s1\">'<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s1\">'<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"c1\"># Break down the request line into components<\/span>\r\n        <span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">request_method<\/span><span class=\"p\">,<\/span>  <span class=\"c1\"># GET<\/span>\r\n         <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">path<\/span><span class=\"p\">,<\/span>            <span class=\"c1\"># \/hello<\/span>\r\n         <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">request_version<\/span>  <span class=\"c1\"># HTTP\/1.1<\/span>\r\n         <span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"n\">request_line<\/span><span class=\"o\">.<\/span><span class=\"n\">split<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">get_environ<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">env<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\r\n        <span class=\"c1\"># The following code snippet does not follow PEP8 conventions<\/span>\r\n        <span class=\"c1\"># but it's formatted the way it is for demonstration purposes<\/span>\r\n        <span class=\"c1\"># to emphasize the required variables and their values<\/span>\r\n        <span class=\"c1\">#<\/span>\r\n        <span class=\"c1\"># Required WSGI variables<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.version'<\/span><span class=\"p\">]<\/span>      <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.url_scheme'<\/span><span class=\"p\">]<\/span>   <span class=\"o\">=<\/span> <span class=\"s1\">'http'<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.input'<\/span><span class=\"p\">]<\/span>        <span class=\"o\">=<\/span> <span class=\"n\">StringIO<\/span><span class=\"o\">.<\/span><span class=\"n\">StringIO<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">request_data<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.errors'<\/span><span class=\"p\">]<\/span>       <span class=\"o\">=<\/span> <span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">stderr<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.multithread'<\/span><span class=\"p\">]<\/span>  <span class=\"o\">=<\/span> <span class=\"bp\">False<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.multiprocess'<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">False<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'wsgi.run_once'<\/span><span class=\"p\">]<\/span>     <span class=\"o\">=<\/span> <span class=\"bp\">False<\/span>\r\n        <span class=\"c1\"># Required CGI variables<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'REQUEST_METHOD'<\/span><span class=\"p\">]<\/span>    <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">request_method<\/span>    <span class=\"c1\"># GET<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'PATH_INFO'<\/span><span class=\"p\">]<\/span>         <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">path<\/span>              <span class=\"c1\"># \/hello<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'SERVER_NAME'<\/span><span class=\"p\">]<\/span>       <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">server_name<\/span>       <span class=\"c1\"># localhost<\/span>\r\n        <span class=\"n\">env<\/span><span class=\"p\">[<\/span><span class=\"s1\">'SERVER_PORT'<\/span><span class=\"p\">]<\/span>       <span class=\"o\">=<\/span> <span class=\"nb\">str<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">server_port<\/span><span class=\"p\">)<\/span>  <span class=\"c1\"># 8888<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">env<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">start_response<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">status<\/span><span class=\"p\">,<\/span> <span class=\"n\">response_headers<\/span><span class=\"p\">,<\/span> <span class=\"n\">exc_info<\/span><span class=\"o\">=<\/span><span class=\"bp\">None<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"c1\"># Add necessary server headers<\/span>\r\n        <span class=\"n\">server_headers<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\r\n            <span class=\"p\">(<\/span><span class=\"s1\">'Date'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'Tue, 31 Mar 2015 12:54:48 GMT'<\/span><span class=\"p\">),<\/span>\r\n            <span class=\"p\">(<\/span><span class=\"s1\">'Server'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'WSGIServer 0.2'<\/span><span class=\"p\">),<\/span>\r\n        <span class=\"p\">]<\/span>\r\n        <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">headers_set<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"n\">status<\/span><span class=\"p\">,<\/span> <span class=\"n\">response_headers<\/span> <span class=\"o\">+<\/span> <span class=\"n\">server_headers<\/span><span class=\"p\">]<\/span>\r\n        <span class=\"c1\"># To adhere to WSGI specification the start_response must return<\/span>\r\n        <span class=\"c1\"># a 'write' callable. We simplicity's sake we'll ignore that detail<\/span>\r\n        <span class=\"c1\"># for now.<\/span>\r\n        <span class=\"c1\"># return self.finish_response<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">finish_response<\/span><span class=\"p\">(<\/span><span class=\"bp\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">result<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\r\n            <span class=\"n\">status<\/span><span class=\"p\">,<\/span> <span class=\"n\">response_headers<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">headers_set<\/span>\r\n            <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'HTTP\/1.1 {status}<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s1\">'<\/span><span class=\"o\">.<\/span><span class=\"n\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">status<\/span><span class=\"o\">=<\/span><span class=\"n\">status<\/span><span class=\"p\">)<\/span>\r\n            <span class=\"k\">for<\/span> <span class=\"n\">header<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">response_headers<\/span><span class=\"p\">:<\/span>\r\n                <span class=\"n\">response<\/span> <span class=\"o\">+=<\/span> <span class=\"s1\">'{0}: {1}<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s1\">'<\/span><span class=\"o\">.<\/span><span class=\"n\">format<\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"n\">header<\/span><span class=\"p\">)<\/span>\r\n            <span class=\"n\">response<\/span> <span class=\"o\">+=<\/span> <span class=\"s1\">'<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s1\">'<\/span>\r\n            <span class=\"k\">for<\/span> <span class=\"n\">data<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">result<\/span><span class=\"p\">:<\/span>\r\n                <span class=\"n\">response<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">data<\/span>\r\n            <span class=\"c1\"># Print formatted response data a la 'curl -v'<\/span>\r\n            <span class=\"k\">print<\/span><span class=\"p\">(<\/span><span class=\"s1\">''<\/span><span class=\"o\">.<\/span><span class=\"n\">join<\/span><span class=\"p\">(<\/span>\r\n                <span class=\"s1\">'&gt; {line}<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"o\">.<\/span><span class=\"n\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">line<\/span><span class=\"o\">=<\/span><span class=\"n\">line<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"k\">for<\/span> <span class=\"n\">line<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">response<\/span><span class=\"o\">.<\/span><span class=\"n\">splitlines<\/span><span class=\"p\">()<\/span>\r\n            <span class=\"p\">))<\/span>\r\n            <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">client_connection<\/span><span class=\"o\">.<\/span><span class=\"n\">sendall<\/span><span class=\"p\">(<\/span><span class=\"n\">response<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">finally<\/span><span class=\"p\">:<\/span>\r\n            <span class=\"bp\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">client_connection<\/span><span class=\"o\">.<\/span><span class=\"n\">close<\/span><span class=\"p\">()<\/span>\r\n\r\n\r\n<span class=\"n\">SERVER_ADDRESS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"n\">HOST<\/span><span class=\"p\">,<\/span> <span class=\"n\">PORT<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">''<\/span><span class=\"p\">,<\/span> <span class=\"mi\">8888<\/span>\r\n\r\n\r\n<span class=\"k\">def<\/span> <span class=\"nf\">make_server<\/span><span class=\"p\">(<\/span><span class=\"n\">server_address<\/span><span class=\"p\">,<\/span> <span class=\"n\">application<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"n\">server<\/span> <span class=\"o\">=<\/span> <span class=\"n\">WSGIServer<\/span><span class=\"p\">(<\/span><span class=\"n\">server_address<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">server<\/span><span class=\"o\">.<\/span><span class=\"n\">set_app<\/span><span class=\"p\">(<\/span><span class=\"n\">application<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">server<\/span>\r\n\r\n\r\n<span class=\"k\">if<\/span> <span class=\"vm\">__name__<\/span> <span class=\"o\">==<\/span> <span class=\"s1\">'__main__'<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"nb\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">argv<\/span><span class=\"p\">)<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">2<\/span><span class=\"p\">:<\/span>\r\n        <span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">exit<\/span><span class=\"p\">(<\/span><span class=\"s1\">'Provide a WSGI application object as module:callable'<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">app_path<\/span> <span class=\"o\">=<\/span> <span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">argv<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\r\n    <span class=\"n\">module<\/span><span class=\"p\">,<\/span> <span class=\"n\">application<\/span> <span class=\"o\">=<\/span> <span class=\"n\">app_path<\/span><span class=\"o\">.<\/span><span class=\"n\">split<\/span><span class=\"p\">(<\/span><span class=\"s1\">':'<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">module<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">__import__<\/span><span class=\"p\">(<\/span><span class=\"n\">module<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">application<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">getattr<\/span><span class=\"p\">(<\/span><span class=\"n\">module<\/span><span class=\"p\">,<\/span> <span class=\"n\">application<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">httpd<\/span> <span class=\"o\">=<\/span> <span class=\"n\">make_server<\/span><span class=\"p\">(<\/span><span class=\"n\">SERVER_ADDRESS<\/span><span class=\"p\">,<\/span> <span class=\"n\">application<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">print<\/span><span class=\"p\">(<\/span><span class=\"s1\">'WSGIServer: Serving HTTP on port {port} ...<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"o\">.<\/span><span class=\"n\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">port<\/span><span class=\"o\">=<\/span><span class=\"n\">PORT<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"n\">httpd<\/span><span class=\"o\">.<\/span><span class=\"n\">serve_forever<\/span><span class=\"p\">()<\/span><\/pre>\n<p>\u4f60\u80af\u5b9a\u5728\u60f3\uff0c\u4ec0\u4e48\u9b3c\uff1f\u8bf4\u597d\u7684\u7b80\u5355\u5b9e\u73b0\u5462\uff1f\uff08\u8bd1\u8005\uff1a\u6211\u4e5f\u5728\u60f3\u4ec0\u4e48\u9b3c\uff01\u8fd9\u4e48\u591a\uff01\uff09\u4f46\u662f\u5b83\u8db3\u591f\u5c0f\u5230\u80fd\u8ba9\u4f60\u7406\u89e3\u5374\u4e0d\u4f1a\u9677\u5165\u5230\u7ec6\u8282\u4e0a\u3002\u4e0a\u9762\u6700\u7b80\u5355\u7684\u670d\u52a1\u5668\u4e5f\u80fd\u505a\u5230\u5f88\u591a\uff0c\u4ed6\u53ef\u4ee5\u8fd0\u884c\u6700\u57fa\u672c\u7684Pyramid\u3001Flask\u3001Django\u6216\u8005\u5176\u4ed6\u7684PythonWSGI\u6846\u67b6\u3002<\/p>\n<p>\u8fd8\u522b\u4e0d\u4fe1\uff0c\u54b1\u4eec\u6765\u8bd5\u8bd5\u3002\u770b\u89c1\u4e0a\u9762\u7684\u4ee3\u7801\u4e86\u5417\uff1f\u76f4\u63a5\u62f7\u4e0b\u6765\u6216\u8005\u4ece<a href=\"https:\/\/github.com\/rspivak\/lsbaws\/blob\/master\/part2\/webserver2.py\">Github<\/a>\u4e0adown\u4e0b\u6765\uff0c\u4fdd\u5b58\u4e3a<em>webserver2.py<\/em>\u6587\u4ef6<em>\u3002<\/em>\u5982\u679c\u4e0d\u52a0\u53c2\u6570\u76f4\u63a5\u8fd0\u884c\u4f1a\u62a5\u9519\u5e76\u9000\u51fa\u3002<\/p>\n<pre>$ python webserver2.py\r\nProvide a WSGI application object as module:callable\r\n<\/pre>\n<p>\u5b83\u771f\u60f3\u4e3a\u4f60\u7684web\u5e94\u7528\u670d\u52a1\uff0c\u5374\u65e0\u4ece\u4e0b\u624b\u3002\u60f3\u8ba9\u8fd9\u4e2a\u670d\u52a1\u5668\u8fd0\u884c\u8d77\u6765\u53ea\u9700\u8981\u5b89\u88c5python\u5c31\u884c\u4e86\uff0c\u4f46\u662f\u60f3\u8981\u8fd0\u884cPyramid\u3001Flask\u3001Django\u7684\u5e94\u7528\uff0c\u8fd8\u5f97\u5148\u5b89\u88c5\u8fd9\u4e9b\u6846\u67b6\u3002\u6211\u63a8\u8350\u7684\u65b9\u6cd5\u662f\u4f7f\u7528\u865a\u62df\u73af\u5883\uff08virtualenv\uff09\u3002\u4f60\u53ea\u8981\u8ddf\u7740\u4e0b\u9762\u7684\u6b65\u9aa4\u4e00\u6b65\u6b65\u6765\u5c31OK\uff0c\u9996\u5148\u5b89\u88c5\u865a\u62df\u73af\u5883\uff0c\u7136\u540e\u5b89\u88c5\u8fd9\u4e09\u4e2a\u6846\u67b6\u3002\uff08\u8bd1\u8005\u8ba4\u4e3a\u53ef\u4ee5\u4e0d\u7528\u865a\u62df\u73af\u5883\uff0c\u76f4\u63a5\u5b89\u88c5\u4e09\u4e2a\u6846\u67b6\uff09<\/p>\n<pre>$ <span class=\"o\">[<\/span>sudo<span class=\"o\">]<\/span> pip install virtualenv\r\n$ mkdir ~\/envs\r\n$ virtualenv ~\/envs\/lsbaws\/\r\n$ <span class=\"nb\">cd<\/span> ~\/envs\/lsbaws\/\r\n$ ls\r\nbin  include  lib\r\n$ <span class=\"nb\">source<\/span> bin\/activate\r\n<span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ pip install pyramid\r\n<span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ pip install flask\r\n<span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ pip install django<\/pre>\n<p>\u8fd9\u65f6\u5019\u8981\u521b\u5efa\u4e00\u4e2aweb\u5e94\u7528\u3002\u8fd9\u91cc\u4ee5Pyramid\u4e3a\u4f8b\u3002\u540c\u6837\u7684\uff0c\u4fdd\u5b58\u4e0b\u9762\u7684\u4ee3\u7801\u6216\u8005\u4ece<a href=\"https:\/\/github.com\/rspivak\/lsbaws\/blob\/master\/part2\/pyramidapp.py\">Github<\/a>\u76f4\u63a5down\u4e0b\u6765\uff0c\u547d\u540d\u4e3apyramidapp.py\u3002\u8ddf\u4f60\u7684webserver2.py\u4fdd\u5b58\u5230\u540c\u4e00\u76ee\u5f55\u4e0b\uff1a<\/p>\n<pre><span class=\"kn\">from<\/span> <span class=\"nn\">pyramid.config<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Configurator<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">pyramid.response<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Response<\/span>\r\n\r\n\r\n<span class=\"k\">def<\/span> <span class=\"nf\">hello_world<\/span><span class=\"p\">(<\/span><span class=\"n\">request<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">Response<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"s1\">'Hello world from Pyramid!<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"n\">content_type<\/span><span class=\"o\">=<\/span><span class=\"s1\">'text\/plain'<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"p\">)<\/span>\r\n\r\n<span class=\"n\">config<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Configurator<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">config<\/span><span class=\"o\">.<\/span><span class=\"n\">add_route<\/span><span class=\"p\">(<\/span><span class=\"s1\">'hello'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'\/hello'<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">config<\/span><span class=\"o\">.<\/span><span class=\"n\">add_view<\/span><span class=\"p\">(<\/span><span class=\"n\">hello_world<\/span><span class=\"p\">,<\/span> <span class=\"n\">route_name<\/span><span class=\"o\">=<\/span><span class=\"s1\">'hello'<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">app<\/span> <span class=\"o\">=<\/span> <span class=\"n\">config<\/span><span class=\"o\">.<\/span><span class=\"n\">make_wsgi_app<\/span><span class=\"p\">()<\/span><\/pre>\n<p>\u73b0\u5728\u4f60\u53ef\u4ee5\u5199\u4e00\u4e2aPyramid\u7a0b\u5e8f\u5e76\u4e14\u7528\u4f60\u521a\u624d\u7684web\u670d\u52a1\u5668\u8fd0\u884c\u4e86\u3002<\/p>\n<pre><span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ python webserver2.py pyramidapp:app\r\nWSGIServer: Serving HTTP on port <span class=\"m\">8888<\/span> ...<\/pre>\n<p>\u4f60\u53ea\u662f\u544a\u8bc9\u4f60\u7684\u670d\u52a1\u5668\u4ecepython\u7684pyramidapp\u6a21\u5757\u4e2d\u52a0\u8f7d\u8fd9\u4e2a\u2018app\u2019\u3002\u4f60\u7684\u670d\u52a1\u5668\u5df2\u7ecf\u51c6\u5907\u597d\u63a5\u6536\u8bf7\u6c42\u5e76\u4e14\u8f6c\u53d1\u7ed9\u4f60\u7684Pyramid\u7a0b\u5e8f\u3002\u73b0\u5728\u4f60\u7684web\u5e94\u7528\u53ea\u5904\u7406\/hello\u8fd9\u4e00\u4e2a\u8def\u7531\u8def\u5f84\u3002\u5728\u4f60\u7684\u6d4f\u89c8\u5668\u4e2d\u8f93\u5165http:\/\/localhost:8888\/hello \u6309\u4e0b\u56de\u8f66\uff0c\u4f60\u4f1a\u53d1\u73b0\uff0c\u795e\u5947\u7684\u64cd\u4f5c\u53c8\u4e00\u6b21\u53d1\u751f\u4e86\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-217 size-full\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_pyramid.png\" alt=\"\" width=\"318\" height=\"122\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_pyramid.png 318w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_pyramid-300x115.png 300w\" sizes=\"(max-width: 318px) 100vw, 318px\" \/><\/p>\n<p>\u540c\u6837\u4f60\u4e5f\u53ef\u4ee5\u4f7f\u7528curl\u547d\u4ee4\u5728\u547d\u4ee4\u884c\u4e2d\u6d4b\u8bd5\u4f60\u7684\u670d\u52a1\u5668\u3002<\/p>\n<pre>$ curl -v http:\/\/localhost:8888\/hello\r\n...\r\n<\/pre>\n<p>\u67e5\u770b\u4e00\u4e0b\u4f7f\u7528curl\u547d\u4ee4\uff0c\u4f60\u7684\u670d\u52a1\u5668\u8f93\u51fa\u4e86\u4ec0\u4e48\u3002<\/p>\n<p>\u73b0\u5728\u6211\u4eec\u4f7f\u7528Flask\u521b\u5efa\u4e00\u4e2a\u540c\u6837web\u5e94\u7528\u3002\u521b\u5efa\u3001\u542f\u52a8\u3001\u8fd0\u884c\u3001\u6d4b\u8bd5\u90fd\u4e0e\u4e0a\u9762\u76f8\u540c\u3002<\/p>\n<pre><span class=\"kn\">from<\/span> <span class=\"nn\">flask<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Flask<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">flask<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Response<\/span>\r\n<span class=\"n\">flask_app<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Flask<\/span><span class=\"p\">(<\/span><span class=\"s1\">'flaskapp'<\/span><span class=\"p\">)<\/span>\r\n\r\n\r\n<span class=\"nd\">@flask_app.route<\/span><span class=\"p\">(<\/span><span class=\"s1\">'\/hello'<\/span><span class=\"p\">)<\/span>\r\n<span class=\"k\">def<\/span> <span class=\"nf\">hello_world<\/span><span class=\"p\">():<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">Response<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"s1\">'Hello world from Flask!<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"n\">mimetype<\/span><span class=\"o\">=<\/span><span class=\"s1\">'text\/plain'<\/span>\r\n    <span class=\"p\">)<\/span>\r\n\r\n<span class=\"n\">app<\/span> <span class=\"o\">=<\/span> <span class=\"n\">flask_app<\/span><span class=\"o\">.<\/span><span class=\"n\">wsgi_app<\/span><\/pre>\n<p>\u4fdd\u5b58\u4e0a\u9762\u7684\u4ee3\u7801\u6216\u8005\u76f4\u63a5\u4ece<a href=\"https:\/\/github.com\/rspivak\/lsbaws\/blob\/master\/part2\/flaskapp.py\">Github<\/a>\u4e0a\u4e0b\u8f7d\uff0c\u4fdd\u5b58\u4e3aflaskapp.py \u4e5f\u662f\u653e\u5728\u540c\u4e00\u6587\u4ef6\u5939\u3002\u5728\u547d\u4ee4\u884c\u4e2d\u8f93\u5165\uff1a<\/p>\n<pre><span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ python webserver2.py flaskapp:app\r\nWSGIServer: Serving HTTP on port <span class=\"m\">8888<\/span> ...<\/pre>\n<p>\u518d\u6b21\u5728\u6d4f\u89c8\u5668\u4e2d\u8f93\u5165 http:\/\/localhost:8888\/hello \u56de\u8f66\uff0c\u795e\u5947\u7684\u64cd\u4f5c\u53c8\u6765\u4e86\uff01\uff08\u5927\u5bb6\u522b\u5acc\u70e6\uff0c\u540e\u9762Django\u8fd8\u8981\u6765\u4e00\u904d&#8230;\uff09<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-218 size-full\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_flask.png\" alt=\"\" width=\"344\" height=\"148\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_flask.png 344w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_flask-300x129.png 300w\" sizes=\"(max-width: 344px) 100vw, 344px\" \/><\/p>\n<p>\u540c\u6837\u4f7f\u7528curl\u547d\u4ee4\u5728\u547d\u4ee4\u884c\u4e2d\u6d4b\u8bd5web\u670d\u52a1\u5668\uff0cFlask\u5e94\u7528\u56de\u4ea7\u751f\u3002\u3002\u3002<\/p>\n<pre>$ curl -v http:\/\/localhost:8888\/hello\r\n...\r\n\r\n<\/pre>\n<p>\u8fd9\u4e2a\u670d\u52a1\u5668\u80fd\u5904\u7406Django\u5e94\u7528\u5417\uff1f\uff08\u771f\u7684\u53c8\u8981\u6765\u4e00\u904d\u3002\u3002\u3002\uff09\u6765\u8bd5\u8bd5\uff01\u4f46\u662f\u8fd9\u6b21\u6709\u70b9\u513f\u590d\u6742\uff0c\u6211\u5efa\u8bae\u4ece<a href=\"https:\/\/github.com\/rspivak\/lsbaws\/\">Github<\/a>\u76f4\u63a5\u628a\u6574\u4e2a\u9879\u76eedown\u4e0b\u6765\uff0c\u53ea\u4f7f\u7528<a href=\"https:\/\/github.com\/rspivak\/lsbaws\/blob\/master\/part2\/djangoapp.py\">djangoapp.py<\/a>\u8fd9\u90e8\u5206\u3002\u8fd9\u662f\u5de5\u7a0b\u7684\u6e90\u4ee3\u7801\uff0c\u53ea\u9700\u8981\u5c06\u2018helloworld\u2019\u8fd9\u4e2aDjango\u5de5\u7a0b\u6dfb\u52a0\u5230\u5f53\u524d\u8def\u5f84\uff0c\u5e76\u4e14\u5c06\u5de5\u7a0b\u7684WSGI\u5e94\u7528\u5bfc\u5165\u3002<\/p>\n<pre><span class=\"kn\">import<\/span> <span class=\"nn\">sys<\/span>\r\n<span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">path<\/span><span class=\"o\">.<\/span><span class=\"n\">insert<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'.\/helloworld'<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">helloworld<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">wsgi<\/span>\r\n\r\n\r\n<span class=\"n\">app<\/span> <span class=\"o\">=<\/span> <span class=\"n\">wsgi<\/span><span class=\"o\">.<\/span><span class=\"n\">application<\/span><\/pre>\n<p>\u4fdd\u5b58\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u547d\u540d\u4e3adjangoapp.py\u7136\u540e\u7528\u4f60\u7684web\u670d\u52a1\u5668\u8fd0\u884c\u8fd9\u4e2a\u7a0b\u5e8f\u3002<\/p>\n<pre><span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ python webserver2.py djangoapp:app\r\nWSGIServer: Serving HTTP on port <span class=\"m\">8888<\/span> ...<\/pre>\n<p>\u7136\u540e\u518d\u6d4f\u89c8\u5668\u4e2d\u8f93\u5165http:\/\/localhost:8888\/hello<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-219 size-full\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_django.png\" alt=\"\" width=\"340\" height=\"135\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_django.png 340w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_django-300x119.png 300w\" sizes=\"(max-width: 340px) 100vw, 340px\" \/><\/p>\n<p>\u524d\u9762\u4f60\u5df2\u7ecf\u505a\u8fc7\u4e24\u6b21\u4e86\uff0c\u8fd9\u6b21\u4f60\u4e5f\u53ef\u4ee5\u5728\u547d\u4ee4\u884c\u4e2d\u6d4b\u8bd5\uff0c\u4ee5\u8fdb\u4e00\u6b65\u786e\u8ba4\u4f60\u7684Django\u7a0b\u5e8f\u80fd\u6b63\u786e\u5904\u7406\u7684\u8bf7\u6c42\uff1a<\/p>\n<pre>$ curl -v http:\/\/localhost:8888\/hello\r\n...<\/pre>\n<p>\u4f60\u786e\u5b9a\u4f60\u8bd5\u8fc7\u4e86\u5417\uff1f\u4f60\u786e\u5b9a\u4f60\u7684\u670d\u52a1\u5668\u652f\u6301\u8fd9\u51e0\u79cd\u6846\u67b6\u5417\uff1f\u5982\u679c\u6ca1\u6709\uff0c\u8bf7\u8ba4\u771f\u505a\u4e00\u904d\u3002\u8bfb\u8fc7\u6587\u7ae0\u548c\u4ee3\u7801\u56fa\u7136\u91cd\u8981\uff0c\u4f46\u8fd9\u4e00\u7cfb\u5217\u6587\u7ae0\u662f\u52a8\u624b\u5f00\u53d1\u81ea\u5df1\u7684web\u670d\u52a1\u5668\uff0c\u8fd9\u610f\u5473\u7740\u4f60\u5fc5\u987b\u81ea\u5df1\u4eb2\u81ea\u52a8\u624b\u5199\u4e00\u904d\u3002\u64b8\u8d77\u8896\u5b50\u52a0\u6cb9\u5e72~\u4f60\u5fc5\u987b\u81ea\u5df1\u4eb2\u81ea\u52a8\u624b\u628a\u4ee3\u7801\u6572\u4e00\u904d\u4ee5\u786e\u4fdd\u80fd\u6309\u7167\u9884\u671f\u8fd0\u884c\u3002<\/p>\n<p>\u76f8\u4fe1\u4f60\u5df2\u7ecf\u89c1\u8bc6\u5230WSGI\u7684\u5f3a\u5927\u4e86\u3002\u5b83\u80fd\u8ba9\u4f60\u968f\u610f\u642d\u914d\u670d\u52a1\u5668\u548cweb\u6846\u67b6\u3002WSGI\u5728Python Web\u670d\u52a1\u5668\u548cPython Web\u6846\u67b6\u4e4b\u95f4\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6781\u7b80\u7684\u63a5\u53e3\u3002\u4e0d\u7ba1\u662f\u5bf9\u4e8e\u6846\u67b6\u8fd8\u662f\u670d\u52a1\u5668\uff0cWSGI\u90fd\u975e\u5e38\u5bb9\u6613\u5b9e\u73b0\u3002\u4e0b\u9762\u7684\u4ee3\u7801\u7247\u6bb5\u5c55\u793a\u4e86\u670d\u52a1\u5668\u548c\u6846\u67b6\u63a5\u53e3\u7684\u4ee3\u7801\u5b9e\u73b0\u3002<\/p>\n<pre><span class=\"k\">def<\/span> <span class=\"nf\">run_application<\/span><span class=\"p\">(<\/span><span class=\"n\">application<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"sd\">\"\"\"Server code.\"\"\"<\/span>\r\n    <span class=\"c1\"># This is where an application\/framework stores<\/span>\r\n    <span class=\"c1\"># an HTTP status and HTTP response headers for the server<\/span>\r\n    <span class=\"c1\"># to transmit to the client<\/span>\r\n    <span class=\"n\">headers_set<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\r\n    <span class=\"c1\"># Environment dictionary with WSGI\/CGI variables<\/span>\r\n    <span class=\"n\">environ<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">start_response<\/span><span class=\"p\">(<\/span><span class=\"n\">status<\/span><span class=\"p\">,<\/span> <span class=\"n\">response_headers<\/span><span class=\"p\">,<\/span> <span class=\"n\">exc_info<\/span><span class=\"o\">=<\/span><span class=\"bp\">None<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">headers_set<\/span><span class=\"p\">[:]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"n\">status<\/span><span class=\"p\">,<\/span> <span class=\"n\">response_headers<\/span><span class=\"p\">]<\/span>\r\n\r\n    <span class=\"c1\"># Server invokes the \u2018application' callable and gets back the<\/span>\r\n    <span class=\"c1\"># response body<\/span>\r\n    <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"n\">application<\/span><span class=\"p\">(<\/span><span class=\"n\">environ<\/span><span class=\"p\">,<\/span> <span class=\"n\">start_response<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"c1\"># Server builds an HTTP response and transmits it to the client<\/span>\r\n    <span class=\"err\">\u2026<\/span>\r\n\r\n<span class=\"k\">def<\/span> <span class=\"nf\">app<\/span><span class=\"p\">(<\/span><span class=\"n\">environ<\/span><span class=\"p\">,<\/span> <span class=\"n\">start_response<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"sd\">\"\"\"A barebones WSGI app.\"\"\"<\/span>\r\n    <span class=\"n\">start_response<\/span><span class=\"p\">(<\/span><span class=\"s1\">'200 OK'<\/span><span class=\"p\">,<\/span> <span class=\"p\">[(<\/span><span class=\"s1\">'Content-Type'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'text\/plain'<\/span><span class=\"p\">)])<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">[<\/span><span class=\"s1\">'Hello world!'<\/span><span class=\"p\">]<\/span>\r\n\r\n<span class=\"n\">run_application<\/span><span class=\"p\">(<\/span><span class=\"n\">app<\/span><span class=\"p\">)<\/span><\/pre>\n<p>\u63a5\u4e0b\u6765\u8bb2\u8bb2\u5b83\u7684\u5de5\u4f5c\u539f\u7406\uff1a<\/p>\n<p>1. \u6846\u67b6\u63d0\u4f9b\u4e00\u4e2a\u53ef\u4f9b\u8c03\u7528\u7684\u2018application\u2019\u5bf9\u8c61\u3002\uff08WSGI\u89c4\u8303\u91cc\u5e76\u6ca1\u6709\u89c4\u5b9a\u8fd9\u4e2aapplication\u8981\u600e\u4e48\u5b9e\u73b0\uff09<\/p>\n<p>2.\u5bf9\u4e8e\u6bcf\u4e2a\u6765\u81eaHTTP\u5ba2\u6237\u7aef\u7684\u8bf7\u6c42\uff0c\u670d\u52a1\u5668\u90fd\u4f1a\u8c03\u7528\u8fd9\u4e2a\u53ef\u8c03\u7528\u7684\u2018application\u2019\u5bf9\u8c61\u3002\u670d\u52a1\u5668\u4f1a\u5411\u53ef\u8c03\u7528\u5bf9\u8c61\u2018application\u2019\u4f20\u9012\u4e00\u4e2a\u540d\u4e3a\u2018environ\u2019\u5b57\u5178\u7c7b\u578b\u7684\u53c2\u6570\uff0c\u5b57\u5178\u91cc\u5305\u542bWSGI\/SGI\u7684\u4e00\u4e9b\u53d8\u91cf\u548c\u4e00\u4e2a\u2018start_response\u2019\u53ef\u8c03\u7528\u5bf9\u8c61\u3002<\/p>\n<p>3.\u6846\u67b6\/\u5e94\u7528\u7a0b\u5e8f\u4f1a\u4ea7\u751f\u4e00\u4e2aHTPP\u72b6\u6001\u548cHTTP\u54cd\u5e94\u62a5\u5934\uff0c\u4f20\u9012\u7ed9\u53ef\u8c03\u7528\u5bf9\u8c61\u2018start_response\u2019\u4ee5\u4f9b\u670d\u52a1\u5668\u50a8\u5b58\u3002\u6846\u67b6\/\u5e94\u7528\u7a0b\u5e8f\u4e5f\u4f1a\u8fd4\u56de\u4e00\u4e2a\u54cd\u5e94\u7684\u4e3b\u4f53\u3002<\/p>\n<p>4.\u670d\u52a1\u5668\u5c06\u72b6\u6001\u7801\u3001\u54cd\u5e94\u5934\u90e8\u3001\u54cd\u5e94\u4e3b\u4f53\u7ec4\u5408\u6210HTTP\u54cd\u5e94\uff0c\u5c06\u5b83\u4f20\u9012\u7ed9\u5ba2\u6237\u7aef\uff08\u8fd9\u4e00\u90e8\u6ca1\u6709\u5728\u89c4\u8303\u91cc\u5199\u51fa\u6765\uff0c\u4f46\u4e3a\u4e86\u4e0b\u4e00\u6b65\u7684\u903b\u8f91\u80fd\u6e05\u6670\u70b9\u513f\uff0c\u6211\u624d\u628a\u5b83\u52a0\u4e0a\uff09\u3002<\/p>\n<p>\u4e0b\u9762\u662f\u63a5\u53e3\u7684\u4e00\u4e2a\u53ef\u89c6\u5316\u8868\u793a\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-220 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interface-1024x689.png\" alt=\"\" width=\"1024\" height=\"689\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interface.png 1024w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interface-300x202.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_wsgi_interface-768x517.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>\u76ee\u524d\u4e3a\u6b62\uff0c\u4f60\u5df2\u7ecf\u89c1\u8bc6\u4e86Pyramid\u3001Flask\u3001Django\u7684Web\u5e94\u7528\uff0c\u670d\u52a1\u5668\u7684WSGI\u63a5\u53e3\u5b9e\u73b0\uff0c\u6ca1\u7528\u4efb\u4f55\u6846\u67b6\u7684WSGI\u5e94\u7528\u7684\u4ee3\u7801\u7247\u6bb5\u3002<\/p>\n<p>\u8fd8\u6709\u4e00\u4ef6\u4e8b\uff0c\u5f53\u4f60\u4f7f\u7528\u4efb\u4f55\u4e00\u79cd\u6846\u67b6\u5199\u4e00\u4e2aweb\u5e94\u7528\u65f6\uff0c\u4f60\u7684\u601d\u60f3\u5728\u4e00\u4e2a\u66f4\u9ad8\u7684\u903b\u8f91\uff0c\u4e0d\u4f1a\u4e0eWSGI\u63a5\u53e3\u76f4\u63a5\u63a5\u89e6\uff0c\u6211\u77e5\u9053\u4f60\u4f1a\u597d\u5947\u6846\u67b6\u7684WSGI\u63a5\u53e3\u662f\u4ec0\u4e48\u6837\u7684\uff0c\u56e0\u4e3a\u4f60\u5728\u8bfb\u8fd9\u7bc7\u6587\u7ae0\u554a\u3002\u6240\u4ee5\u6211\u65e9\u5c31\u51c6\u5907\u597d\u4e86\u4e00\u4e2a\u4e0d\u7528\u5404\u79cd\u6846\u67b6\u5c31\u80fd\u5728\u670d\u52a1\u5668\u4e0a\u8fd0\u884c\u7684WSGI Web\u5e94\u7528\/Web\u6846\u67b6\u3002<\/p>\n<pre><span class=\"k\">def<\/span> <span class=\"nf\">app<\/span><span class=\"p\">(<\/span><span class=\"n\">environ<\/span><span class=\"p\">,<\/span> <span class=\"n\">start_response<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"sd\">\"\"\"A barebones WSGI application.<\/span>\r\n\r\n<span class=\"sd\">    This is a starting point for your own Web framework :)<\/span>\r\n<span class=\"sd\">    \"\"\"<\/span>\r\n    <span class=\"n\">status<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'200 OK'<\/span>\r\n    <span class=\"n\">response_headers<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[(<\/span><span class=\"s1\">'Content-Type'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'text\/plain'<\/span><span class=\"p\">)]<\/span>\r\n    <span class=\"n\">start_response<\/span><span class=\"p\">(<\/span><span class=\"n\">status<\/span><span class=\"p\">,<\/span> <span class=\"n\">response_headers<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">[<\/span><span class=\"s1\">'Hello world from a simple WSGI application!<\/span><span class=\"se\">\\n<\/span><span class=\"s1\">'<\/span><span class=\"p\">]<\/span><\/pre>\n<p>\u4fdd\u5b58\u4e0a\u9762\u7684\u4ee3\u7801\u6216\u8005\u76f4\u63a5\u4ece<a href=\"https:\/\/github.com\/rspivak\/lsbaws\/blob\/master\/part2\/wsgiapp.py\">Github<\/a>\u4e0adown\u4e0b\u6765\uff0c\u4fdd\u5b58\u4e3awsgiapp.py\u6587\u4ef6\uff0c\u4e0e\u4f60\u7684\u670d\u52a1\u5668\u4fdd\u5b58\u5728\u540c\u4e00\u8def\u5f84\u3002\u8fd9\u6837\u5c31\u53ef\u4ee5\u8fd0\u884c\u4e86\uff1a<\/p>\n<pre><span class=\"o\">(<\/span>lsbaws<span class=\"o\">)<\/span> $ python webserver2.py wsgiapp:app\r\nWSGIServer: Serving HTTP on port <span class=\"m\">8888<\/span> ...<\/pre>\n<p>\u5728\u6d4f\u89c8\u5668\u5730\u5740\u680f\u4e2d\u8f93\u5165http:\/\/localhost:8888\/hello\uff0c\u4f60\u5c31\u80fd\u770b\u89c1\u5982\u4e0b\u7ed3\u679c\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-221 size-full\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_simple_wsgi_app.png\" alt=\"\" width=\"374\" height=\"156\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_simple_wsgi_app.png 374w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_browser_simple_wsgi_app-300x125.png 300w\" sizes=\"(max-width: 374px) 100vw, 374px\" \/><\/p>\n<p>\u5b66\u4e60\u5f00\u53d1web\u670d\u52a1\u5668\u7684\u65f6\u5019\uff0c\u4f60\u8fd8\u5199\u4e86\u4e2a\u6700\u7b80\u5355\u7684WSGI Web\u6846\u67b6\uff0c\u60ca\u4e0d\u60ca\u559c\uff1f\u610f\u4e0d\u610f\u5916\uff1f<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8f6c\u5411\u670d\u52a1\u5668\u4f20\u9012\u7ed9\u5ba2\u6237\u7aef\u7684HTPP\u62a5\u6587\u3002\u4e0b\u9762\u662f\u4f60\u4f7f\u7528HTTP\u5ba2\u6237\u7aef\u8c03\u7528Pyramid\u5e94\u7528\u65f6\uff0c\u670d\u52a1\u5668\u4ea7\u751f\u7684HTTP\u54cd\u5e94\u62a5\u6587\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-222 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response-1024x519.png\" alt=\"\" width=\"1024\" height=\"519\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response.png 1024w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response-300x152.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response-768x389.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>\u8fd9\u4e2a\u54cd\u5e94\u4e0e\u4f60\u518dPart1\u4e2d\u89c1\u5230\u7684\u6709\u76f8\u4f3c\u4e4b\u5904\uff0c\u4e5f\u6709\u4e00\u4e9b\u65b0\u4e1c\u897f\u3002\u518d\u4e3e\u4e2a\u6817\u5b50\uff0c\u5b83\u6709\u56db\u4e2a\u4f60\u4ee5\u524d\u6ca1\u89c1\u8fc7\u7684HTTP\u5934\u90e8\uff1aContent-Type\u3001Content-Length\u3001Date\u548cServer\u3002\u8fd9\u4e9b\u5934\u90e8\u662f\u4e00\u4e2aweb\u670d\u52a1\u5668\u4ea7\u751f\u7684\u54cd\u5e94\u5e94\u8be5\u6709\u7684\uff0c\u5c3d\u7ba1\u5e76\u6ca1\u6709\u4e25\u683c\u8981\u6c42\u3002\u8fd9\u4e9b\u5934\u90e8\u7684\u76ee\u7684\u662f\u4f20\u9012\u4e00\u4e9b\u5173\u4e8eHTTP\u8bf7\u6c42\/\u54cd\u5e94\u7684\u9644\u52a0\u4fe1\u606f\u3002<\/p>\n<p>\u65e2\u7136\u4f60\u5df2\u7ecf\u5bf9WSGI\u63a5\u53e3\u6709\u4e86\u8fdb\u4e00\u6b65\u7684\u4e86\u89e3\uff0c\u4e0b\u56fe\u8fd8\u662f\u90a3\u4e2aHTTP\u54cd\u5e94\uff0c\u4e0d\u8fc7\u591a\u4e86\u4e9b\u5185\u5bb9\uff0c\u544a\u8bc9\u4f60\u54cd\u5e94\u7684\u6bcf\u6761\u4fe1\u606f\u662f\u4ece\u54ea\u91cc\u4ea7\u751f\u7684\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-223 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response_explanation-1024x500.png\" alt=\"\" width=\"1024\" height=\"500\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response_explanation.png 1024w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response_explanation-300x146.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_http_response_explanation-768x375.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>\u76ee\u524d\u4e3a\u6b62\u6211\u8fd8\u6ca1\u6709\u63d0\u53ca\u2018environ\u2019\u8fd9\u4e2a\u5b57\u5178\uff0c\u7b80\u5355\u6765\u8bf4\u2018environ\u2019\u662f\u4e2a\u6807\u51c6\u7684Python\u5b57\u5178\u7c7b\u578b\uff0c\u5b83\u5fc5\u987b\u5305\u542bWSGI\u89c4\u8303\u91cc\u89c4\u5b9a\u7684\u4e00\u4e9b\u7279\u5b9a\u7684WSGI\u548cSGI\u53d8\u91cf\u3002\u670d\u52a1\u5668\u89e3\u6790\u8bf7\u6c42\u4e4b\u540e\u4eceHTTP\u8bf7\u6c42\u4e2d\u83b7\u53d6\u5b57\u5178\u6240\u9700\u8981\u7684\u503c\u3002\u4e0b\u56fe\u662f\u5b57\u5178\u5185\u5bb9\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-224 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_environ-1024x669.png\" alt=\"\" width=\"1024\" height=\"669\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_environ.png 1024w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_environ-300x196.png 300w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_environ-768x502.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>web\u6846\u67b6\u4ece\u5b57\u5178\u4e2d\u83b7\u53d6\u4fe1\u606f\uff0c\u6839\u636e\u7279\u5b9a\u7684\u8def\u7531\u3001\u8bf7\u6c42\u65b9\u6cd5\u7b49\u6765\u51b3\u5b9a\u4f7f\u7528\u54ea\u4e2a\u9875\u9762\u3001\u4ece\u54ea\u91cc\u8bfb\u53d6\u8bf7\u6c42\u4e3b\u4f53\uff0c\u6216\u8005\u5199\u5165\u9519\u8bef\u4fe1\u606f\u3002<\/p>\n<p>\u76ee\u524d\u4e3a\u6b62\uff0c\u5199\u8fc7\u4e86WSGI Web\u670d\u52a1\u5668\uff0c\u4f7f\u7528\u5404\u79cd\u6846\u67b6\u5199\u8fc7Web\u5e94\u7528\uff0c\u5199\u8fc7\u6700\u57fa\u672c\u7684web\u5e94\u7528\/web\u6846\u67b6\uff0c\u771f\u771f\u662f\u53ef\u6015\u7684\u5669\u68a6\u3002\u4e00\u8d77\u6765\u6982\u62ec\u4e0b\u4f60\u7684WSGIweb\u670d\u52a1\u5668\u9488\u5bf9\u4e00\u4e2aWSGI\u5e94\u7528\u90fd\u8981\u5904\u7406\u54ea\u4e9b\u8bf7\u6c42\u3002<\/p>\n<p>1.\u670d\u52a1\u5668\u542f\u52a8\u5e76\u4e14\u52a0\u8f7d\u4e00\u4e2aweb\u5e94\u7528\/web\u6846\u67b6\u63d0\u4f9b\u7684\u2018application\u2019\u53ef\u8c03\u7528\u5bf9\u8c61\u3002<\/p>\n<p>2.\u670d\u52a1\u5668\u8bfb\u53d6\u4e00\u4e2a\u8bf7\u6c42<\/p>\n<p>3.\u670d\u52a1\u5668\u89e3\u6790\u8fd9\u4e2a\u8bf7\u6c42<\/p>\n<p>4.\u670d\u52a1\u5668\u521b\u5efa\u4f7f\u7528\u8bf7\u6c42\u7684\u6570\u636e\u521b\u5efa\u4e00\u4e2a\u2018environ\u2019\u7684\u5b57\u5178<\/p>\n<p>5.\u8c03\u7528\u53ef\u8c03\u7528\u5bf9\u8c61\u2018application\u2019\uff0c\u4f7f\u7528\u2018environ\u2019\u5b57\u5178\u548c\u53ef\u8c03\u7528\u5bf9\u8c61\u2018start_response\u2019\u4f5c\u4e3a\u53c2\u6570\uff0c\u5f97\u5230\u4e00\u4e2a\u54cd\u5e94\u4e3b\u4f53\u3002<\/p>\n<p>6.\u4f7f\u7528\u53ef\u8c03\u7528\u5bf9\u8c61\u2018application\u2019\u8fd4\u56de\u7684\u6570\u636e\u3001\u72b6\u6001\u7801\u3001\u53ef\u8c03\u7528\u5bf9\u8c61\u2018start_response\u2019\u8bbe\u7f6e\u7684\u54cd\u5e94\u5934\u90e8\u3002<\/p>\n<p>7.\u6700\u540e\u670d\u52a1\u5668\u628a\u8fd9\u4e2aHTTP\u54cd\u5e94\u53d1\u9001\u56de\u5ba2\u6237\u7aef\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-239 size-large\" src=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_server_summary_copy-644x1024.jpg\" alt=\"\" width=\"644\" height=\"1024\" srcset=\"http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_server_summary_copy-644x1024.jpg 644w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_server_summary_copy-189x300.jpg 189w, http:\/\/zkeeer.space\/wp-content\/uploads\/2017\/07\/lsbaws_part2_server_summary_copy-768x1220.jpg 768w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/p>\n<p>\u4e0a\u9762\u5c31\u662f\u6240\u6709\u7684\u5185\u5bb9\u4e86\uff0c\u4f60\u5df2\u7ecf\u6709\u4e00\u4e2a\u53ef\u4ee5\u5de5\u4f5c\u7684WSGI\u670d\u52a1\u5668\u4e86\uff0c\u4ed6\u53ef\u4ee5\u8fd0\u884c\u4e0eWSGI\u517c\u5bb9\u7684web\u6846\u67b6\u4f8b\u5982Flask\u3001Django\u3001Pyramid\u6216\u8005\u4f60\u81ea\u5df1\u7684WSGI\u6846\u67b6\u3002\u6700\u68d2\u7684\u662f\u4e0d\u7528\u4fee\u6539\u4efb\u4f55\u4ee3\u7801\u5c31\u53ef\u4ee5\u4f7f\u7528\u4e0d\u540c\u7684web\u6846\u67b6\u3002\u54ce\u54df\uff0c\u4e0d\u9519\u54df\uff01<\/p>\n<p>\u7559\u4e00\u4e2a\u8bfe\u540e\u601d\u8003\u9898\uff0c\u201c\u600e\u6837\u4fdd\u8bc1\u4f60\u7684\u670d\u52a1\u5668\u80fd\u5728\u540c\u4e00\u65f6\u95f4\u5904\u7406\u591a\u4e2a\u8bf7\u6c42\uff1f\u201d<\/p>\n<p>\u656c\u8bf7\u5173\u6ce8\uff0c\u6211\u4f1a\u5728Part 3\u4e2d\u8bb2\u89e3\u3002\u8001\u94c1\u4eec\uff0c\u53cc\u51fb\u8bc4\u8bba666\uff0c\u5c0f\u706b\u7bad\u8d70\u4e00\u6ce2\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u94fe\u63a5\uff1aLet\u2019s Build A W &hellip; <a href=\"http:\/\/zkeeer.space\/?p=212\" class=\"more-link\">More <span class=\"screen-reader-text\">\u3010\u7ffb\u8bd1\u3011\u4e00\u6b65\u6b65\u5f00\u53d1\u4e00\u4e2aWeb\u670d\u52a1\u5668.Part 2.<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,7],"tags":[11,27],"_links":{"self":[{"href":"http:\/\/zkeeer.space\/index.php?rest_route=\/wp\/v2\/posts\/212"}],"collection":[{"href":"http:\/\/zkeeer.space\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/zkeeer.space\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/zkeeer.space\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/zkeeer.space\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=212"}],"version-history":[{"count":5,"href":"http:\/\/zkeeer.space\/index.php?rest_route=\/wp\/v2\/posts\/212\/revisions"}],"predecessor-version":[{"id":298,"href":"http:\/\/zkeeer.space\/index.php?rest_route=\/wp\/v2\/posts\/212\/revisions\/298"}],"wp:attachment":[{"href":"http:\/\/zkeeer.space\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/zkeeer.space\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=212"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/zkeeer.space\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}