{ "info": { "author": "Dave Shawley", "author_email": "daveshawley@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 1 - Planning", "Framework :: Setuptools Plugin", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "hypermedia\n==========\n\n*\"REST APIs must be hypertext-driven\"*, Roy T. Fielding\n\n|Version| |Downloads| |Status| |License|\n\nWait... Why?\n------------\nThe \"Why\" is pretty simple... there are an abundance of frameworks that\nmake things *RESTful* by generating deterministic URLs for your database\nobjects. Then you implement the popular HTTP methods to provide a nice\nway to interact with your newly minted resources. Congratulations, you\nhave successfully mapped SQL into HTTP. The URL has become your ``WHERE``\nclause and ``PUT``, ``POST``, and ``GET`` are synonyms for ``UPDATE``,\n``INSERT`` and ``SELECT``.\n\nSo that is a *very* tongue-in-cheek answer for *why did I feel the need\nto write this library*. However it is not a great answer nor even an\nacceptable one in my opinion. The *why* is much more nuanced than that.\nThe implementation that I just ranted about may indeed be quite RESTful\nbut we need to know more about a solution than its URL structure and how\nit interprets various protocol actions before we can make that decision.\nThis isn't a dissertation on the Representation State Transfer\narchitectural principles, I leave that to `Dr. Fielding`_. This library\nattempts to provide a few mechanisms to make developing RESTful protocols\nsimpler.\n\n.. Random notes for geeks that read the ReST source\n.. \"Hypermedia is defined by the presence of application control\n.. information embedded within, or as a layer above, the presentation\n.. of information.\" - Roy T. Fielding.\n..\n.. RFC-5988: Link Header\n.. RFC-6570: URI Template\n\nWhat?\n-----\nThis library offers functionality that simplifies writing RESTful service\nimplementations over an existing HTTP server stack such as `Flask`_ or\n`Tornado`_. The HTTP stacks provide very clean and usable ways to\nconstruct URLs and route HTTP requests to specific chunks of code. I'm\nnot going to implement that again. Instead, this library provides ways\nto embed hypermedia controls into your responses without introducing lots\nof nasty coupling in your application code.\n\nThis library is essentially an on-ramp to supporting Hypermedia Controls\nin your HTTP application. *Hypermedia Controls* referring to what is known\nas Level 3 of the `Richardson Maturity Model`_. This model was described\nby Leonard Richardson at QCon in 2008 and has been further examined in\nJim Webber's most excellent `REST in Practice`_. Here is a brief recap:\n\n*Level Zero*\n\n One URL, one HTTP method - ``POST``. Document describes the function\n to invoke, parameters, etc. Response is the *return value*.\n\n *\"There's a little web-based peephole into some other universe, and\n you can only communicate wit the other universe by passing messages\n through the peephole.\"* - L. Richardson.\n\n*Level One: Resources*\n\n URLs identify resources but interactions are limited to sending a\n message that describes the function to invoke, parameters, etc.\n The interactions with different resources instances usually\n depend on URL patterns.\n\n*Level Two: HTTP*\n\n Resources are still identified by constructed URLs but interactions\n follow the rules of HTTP with respect to its verbs (methods). This\n is where most RESTful APIs stop.\n\n*Level Three: Hypermedia Controls*\n \n This is where the seldom understood and inpronouncable term `HATEOAS`_\n shows up. Instead of the URL being formulated by the user of the\n service based on what they want to do and some URL pattern syntax, the\n available actions are represented directly in the document as named\n links. See `REST APIs must by hypertext-driven`_ for a\n well-written and relatively short rationale.\n\nThat is the part of the story that this library attempts to fill. It\nlets you write code like::\n\n from hypermedia.tornado import mixins\n from tornado import web\n\n\n class PersonHandler(mixins.Linker, web.RequestHandler):\n \n def get(self, uid):\n person = get_person_information(uid)\n self.add_link('related-shows', SearchHandler, 'GET',\n person_id=uid, type='shows')\n self.add_link('related-movies', SearchHandler, 'GET',\n person_id=uid, type='movies')\n self.add_link('add-comment', CommentHandler, 'POST', uid=uid)\n self.add_link('comments', CommentHandler, 'GET', uid=uid)\n\n response = {}\n # ... build out the response\n response['links'] = self.get_link_map()\n\n self.write(response)\n\n class SearchHandler(web.RequestHandler):\n\n def get(self):\n # processes query parameters\n\n class CommentHandler(web.RequestHandler):\n\n def get(self, uid):\n # retrieve comments\n\n def post(self, uid):\n # add a comment\n\nThe ``hypermedia.tornado.mixins.Linker`` class takes care of constructing\nthe appropriate links based on the registered handlers and makes them\navailable via the ``get_link_map()`` method.\n\nOk... Where?\n------------\n\n+---------------+-------------------------------------------------+\n| Source | https://github.com/dave-shawley/hypermedia |\n+---------------+-------------------------------------------------+\n| Status | https://travis-ci.org/dave-shawley/hypermedia |\n+---------------+-------------------------------------------------+\n| Download | https://pypi.python.org/pypi/hypermedia |\n+---------------+-------------------------------------------------+\n| Documentation | http://hypermedia.readthedocs.org/en/latest |\n+---------------+-------------------------------------------------+\n| Issues | https://github.com/dave-shawley/hypermedia |\n+---------------+-------------------------------------------------+\n\n.. _Dr. Fielding: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm\n.. _Flask: http://flask.pocoo.org\n.. _HATEOAS: http://www.slideshare.net/d0nn9n/jimwebber-rest\n.. _REST APIs must by hypertext-driven: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven\n.. _REST in Practice: http://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=jimwebbesblog-20&linkCode=xm2&camp=1789&creativeASIN=0596805829\n.. _Richardson Maturity Model: http://www.crummy.com/writing/speaking/2008-QCon/act3.html\n.. _Tornado: http://tornadoweb.org\n\n.. |Version| image:: https://pypip.in/version/hypermedia/badge.svg\n :target: https://pypi.python.org/pypi/hypermedia\n.. |Downloads| image:: https://pypip.in/d/hypermedia/badge.svg\n :target: https://pypi.python.org/pypi/hypermedia\n.. |Status| image:: https://travis-ci.org/dave-shawley/hypermedia.svg\n :target: https://travis-ci.org/dave-shawley/hypermedia\n.. |License| image:: https://pypip.in/license/hypermedia/badge.svg\n :target: https://hypermedia.readthedocs.org/", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/dave-shawley/hypermedia", "keywords": "", "license": "UNKNOWN", "maintainer": "", "maintainer_email": "", "name": "hypermedia", "package_url": "https://pypi.org/project/hypermedia/", "platform": "any", "project_url": "https://pypi.org/project/hypermedia/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/dave-shawley/hypermedia" }, "release_url": "https://pypi.org/project/hypermedia/0.0.0/", "requires_dist": null, "requires_python": null, "summary": "Links representations together.", "version": "0.0.0" }, "last_serial": 1373928, "releases": { "0.0.0": [] }, "urls": [] }