{ "info": { "author": "Tom Willis", "author_email": "tom.willis@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: Public Domain", "Programming Language :: Python", "Programming Language :: Python :: 3" ], "description": ".. WebOb Toolkit documentation master file, created by\n sphinx-quickstart on Sat Mar 8 09:00:00 2014.\n You can adapt this file completely to your liking, but it should at least\n contain the root `toctree` directive.\n\nWebOb Toolkit: Requests for Aliens!\n===================================\n\nWebOb Toolkit is a tool kit for building HTTP_ clients using WebOb_\nrequest and response objects and `wsgi middleware`_.\n\nYou may already be familiar with Webob_ request and response objects\nif you have experience with a web framework that uses them such as\npyramid_ or WebTest_ .\n\n\nUsage\n-----\n\nHere are some examples of how WebOb Toolkit can be used.\n\n\nA Very Simple HTTP Client\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf you didn't know, WebOb's Request object grew a \"get_response_\" method for\nsending an http request to either a wsgi application, or a url and\nreturning the response. ::\n\n >>> from webob import Request\n >>> str(Request.blank(\"https://google.com\").get_response())\n '301 Moved Permanently\\nLocation: https://www.google.com/\\nContent-Type: text/html; charset=UTF-8\\nDate: Sat, 08 Mar 2014 14:58:59 GMT\\nExpires: Mon, 07 Apr 2014 14:58:59 GMT\\nCache-Control: public, max-age=2592000\\nServer: gws\\nContent-Length: 220\\nX-XSS-Protection: 1; mode=block\\nX-Frame-Options: SAMEORIGIN\\nAlternate-Protocol: 443:quic\\n\\n\\n301 Moved\\n

301 Moved

\\nThe document has moved\\nhere.\\r\\n\\r\\n'\n >>> \n\n\nThat is a pretty neat trick, but as http clients go, typically you\nneed other functionality like handling `http compression`_ for example\nor `handling cookies`_. \n\nWebOb Toolkit provides this additional functionality as `wsgi\nmiddleware`_ which allows you to compose your own solutions in much\nthe same way as you compose wsgi applications to be used as HTTP_\nServers.\n\nHandling Compression\n~~~~~~~~~~~~~~~~~~~~\n\nAccording to the `http compression`_ article on wikipedia, an http\nclient can request a compressed response by including an\n\"Accept-Encoding\" header with the request. In WebOb_ you would\ndo... ::\n\n >>> from webob import Request\n >>> Request.blank(\"https://github.com\", headers={\"Accept-Encoding\": \"gzip, deflate\"}).get_response().headers.get(\"Content-Encoding\", \"Content was not encoded\")\n 'gzip'\n >>> \n\nAs you can see, we requested gzipped content from github, and it\nresponded nicely. However, if we were to do anything with the body of\nthe response we would have to uncompress it first. So, it seems that\nthe rules for compression is to a header with each request and\nuncompress the body of each response if the response includes a\n\"Content-Encoding\" header.\n\n\nThe next example, uses webobtoolkit's decode_filter to handle\ncompressed responses. ::\n\n >>> from webob import Request\n >>> from webob.client import send_request_app as app\n >>> from webobtoolkit.filters import decode_filter\n >>> app_gzip = decode_filter(app)\n >>> Request.blank(\"https://github.com\", headers={\"Accept-Encoding\": \"gzip\"}).get_response(app).body[:100]\n '\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\xdd[\\xdbr\\xe4\\xc6\\x91}\\xf7W\\x94\\x9b\\x1b\\xa3\\xdd0\\xd1\\xf7\\x1b9M:\\xe6B\\xd9\\xb3\\xb6%\\xda\\x1cY\\x92\\x1d\\x0eF5Ph`\\x08\\xa0 \\\\H\\xf6\\xfc\\x98\\xdf\\xf7\\xcb|\\xb2\\xaa\\x00\\x14\\xd0M69Kk\\xbdV\\x84\\xa6\\x9b@]\\xb32O\\x9e\\xcc\\xac^\\xfd\\xf2\\xfd\\xb7\\xef>\\xfexy\\xc1\\x82\"\\x8e\\xce\\x7f'\n >>> Request.blank(\"https://github.com\", headers={\"Accept-Encoding\": \"gzip\"}).get_response(app_gzip).body[:100]\n '\\n\\n >> \n\n\n\nFrom the above example you will notice a couple of differences from\nprevious examples. Firstly we are importing WebOb's send_request_app_\nand some `wsgi middleware`_ from webobtoolkit for handling compressed\nresponses. We wrap webob's app with the decode_filter to create an app\nthat will decompress any response we may encounter.\n\nThe first call to github is through webobs app. And as you can see,\nthe response is compressed just like we asked. The second call is\nthrough the new app we created by wrapping webob's app with\nwebobtoolkits decode_filter, and as you can see the response has been\ndecompressed.\n\nThe name \"filter\" is being used here to differentiate between `wsgi\nmiddleware`_ which is usually used in the context of servers and `wsgi\nmiddleware`_ that is intended for use with clients. Filters and\nmiddleware are identical in regards to how they are implemented.\n\nHere is how the decode_filter is implemented. As you can see, it\ndoesn't take much to write a filter.\n\n.. literalinclude:: ../../../webobtoolkit/webobtoolkit/filters.py\n :pyobject: decode_filter\n\n\nA More Robust HTTP Client\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nrequests_ is a good example of a more useful http client. According to\nthe docs it includes a lot of useful things that one would want for in\nan http client. Some of the things it includes are.\n\n* handling compression\n* handling cookies\n* handling redirects\n* guessing, handling charset decoding\n* connection pooling\n* ssl verification\n* form posts\n* file uploads\n\nAnd probably much more. \n\nA lot of this functionality can be written on top of webob and a\nseries of filters. We've already seen how one might handle\ncompression. WebOb toolkit provides filters for handling cookies,\nredirects and handling unspecified charsets. ::\n\n >>> from webob import Request\n >>> from webob.client import send_request_app\n >>> from webobtoolkit import filters\n >>> requests_app = filters.auto_redirect_filter(filters.cookie_filter(filters.decode_filter(filters.charset_filter(send_request_app))))\n >>> Request.blank(\"https://google.com\").get_response(requests_app)\n >>> str(Request.blank(\"https://google.com\").get_response(requests_app))[:500]\n '200 OK\\nDate: Sat, 08 Mar 2014 17:35:40 GMT\\nExpires: -1\\nCache-Control: private, max-age=0\\nContent-Type: text/html; charset=ISO-8859-1\\nServer: gws\\nX-XSS-Protection: 1; mode=block\\nX-Frame-Options: SAMEORIGIN\\n\\n