{ "info": { "author": "Ask Solem", "author_email": "askh@opera.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Communications", "Topic :: Internet :: WWW/HTTP" ], "description": "============================================================================\ndurian - Web Hooks for Django\n============================================================================\n\n:Version: 0.1.0\n\n.. image:: http://cloud.github.com/downloads/ask/durian/webhooks-logo.png\n\nIntroduction\n============\n\nWe want the web sites we create to communicate with other sites. To enable\nthis we give the clients an URL they can connect to. This is fine for most\nrequests, but let's take a look at RSS.\n\nRSS publishes your articles for others to subscribe to. Whenever you have a\nnew article to publish you add it to the RSS document available at an URL\nlike::\n\n http://example.com/articles.rss\n\nThe client connects to this URL, say, every 20 minutes to check if there's\nsomething new. And if there is something new, it has to re-download the entire\ncontent, even if it already has some of the articles from before.\nWe call this communication method `pulling`_.\n\nThis is where web hooks (or HTTP callbacks) comes in, instead of giving the\nclients an URL they can connect to, the clients *give you an URL* you connect\nto every time there is something to update.\n\nBy `pushing`_ instead of pulling the updates, both you\nand your clients saves bandwidth, sometimes by a lot.\n\n.. image:: http://cloud.github.com/downloads/ask/durian/webhook-callback2.png\n\nYou can read more about web hooks at the `Web Hooks Blog`_.\nThese slides by Jeff Lindsay is a good introduction to the subject:\n`Using Web Hooks`_.\n\n.. _`Web Hooks Blog`: http://blog.webhooks.org\n.. _`Using Web Hooks`:\n http://www.slideshare.net/progrium/using-web-hooks\n.. _`pushing`: http://en.wikipedia.org/wiki/Push_technology\n.. _`pulling`: http://en.wikipedia.org/wiki/Pull_technology\n\n**NOTE** This software is just in the planning stage and is going to\nchange drastically. You can follow what is happening here, and is welcome to\nhelp out making it happen, but you should probably not use it for anything\nuntil it has reached an alpha version.\n\n\nExamples\n========\n\nCreating an event with a model and a signal\n-------------------------------------------\n\nIn this example we'll be creating a ModelHook.\n\nA ModelHook is a hook which takes a Django model and signal.\nSo whenever that signal is fired, the hook is also triggered.\n\nYou can specify which of the model fields you want to pass on to the listeners\nvia the ``provides_args`` attribute.\n\n\nFirst let's create a simple model of a person storing the persons\nname, address and a secret field we don't want to pass on to listeners:\n\n >>> from django.db import models\n >>> from django.utils.translation import ugettext_lazy as _\n\n >>> class Person(models.Model):\n ... name = models.CharField(_(u\"name\"), blank=False, max_length=200)\n ... address = models.CharField(_(u\"address\"), max_length=200)\n ... secret = models.CharField(_(u\"secret\"), max_length=200)\n\n\nNow to the hook itself. We subclass the ModelHook class and register it in\nthe global webhook registry. For now we'll set ``async`` to False, this means\nthe tasks won't be sent to ``celeryd`` but executed locally instead. In\nproduction you would certainly want the dispatch to be asynchronous.\n \n >>> from durian.event import ModelHook\n >>> from durian.registry import hooks\n >>> from django.db.models import signals\n\n \n >>> class PersonHook(ModelHook):\n ... name = \"person\"\n ... model = Person\n ... signal = signals.post_save\n ... provides_args = [\"name\", \"address\"]\n ... async = False\n >>> hooks.register(PersonHook)\n\nNow we can create ourselves some listeners. They can be created manually\nor by using the web-interface. A listener must have a URL, which is the\ndestination callback the signal is sent to, and you can optionally filter\nevents so you only get the events you care about.\n\n >>> # send event when person with name Joe is changed/added.\n >>> PersonHook().listener(\n ... url=\"http://where.joe/is/listening\").match(\n ... name=\"Joe\").save()\n\n >>> # send event whenever a person with a name that starts with the\n >>> # letter \"J\" is changed/added:\n >>> from durian.match import Startswith\n >>> PersonHook().listener(\n ... url=\"http://where.joe/is/listening\").match(\n ... name=Startswith(\"J\").save()\n\n >>> # send event when any Person is changed/added.\n >>> PersonHook().listener(url=\"http://where.joe/is/listening\").save()\n\nThe filters can use special matching classes, as you see with the\n``Startswith`` above. See `Matching classes`_ for a list of these.\n\nIn this screenshot you can see the view for selecting the person event:\n\n.. image:: \n http://cloud.github.com/downloads/ask/durian/durian-shot-select_event.png\n\nand then creating a listener for that event:\n\n.. image::\n http://cloud.github.com/downloads/ask/durian/durian-shot-create_listenerv2.png\n\n\nCreating custom hooks\n---------------------\n\nSometimes you'd like to create hooks for something else than a model.\nIf there's already a Django signal you want to bind to there is the\n``SignalHook``. Otherwise you can send your own signal by creating a custom\n``Hook``.\n \nThe only required attribute of a hook is the name, so it can be uniquely\nidentified in the hook registry.\n\nThere are two ways of defining a hook, either by instantiation a Hook\nclass, or by subclassing one. You can register a hook instance, or a hook\nclass, it doesn't matter as long as the name is different:\n\n >>> from durian.registry import hooks\n\n >>> # Defining a hook by instantiating a hook class:\n >>> myhook = Hook(name=\"myhook\")\n >>> hooks.register(myhook)\n\n >>> # Defining a hook by subclassing a hook class:\n >>> class MyHook(Hook):\n ... name = \"myhook\"\n >>> hooks.register(MyHook)\n\n\nThese also supports the ``provides_args`` attribute which can automatically\ngenerate event filter forms.\n\nSee the API reference for a complete list of ``Hook`` arguments and\nattributes.\n\nTriggering a hook is simple by using the ``send`` method::\n\n >>> class MyHook(Hook):\n ... name = \"myhook\"\n ... provides_args = [\"name\", \"address\"]\n ... async = False\n >>> hooks.register(MyHook)\n\n >>> MyHook().send(sender=None,\n ... name=\"George Constanza\", address=\"New York City\")\n\n\nView for listening URL\n----------------------\n\n >>> from django.http import HttpResponse\n >>> from anyjson import deserialize\n\n >>> def listens(request):\n ... payload = deserialize(request.raw_post_data)\n ... print(payload[\"name\"])\n ... return HttpResponse(\"thanks!\")\n\n\nMatching classes\n----------------\n\n\n * Any()\n Matches anything. Even if the field is not sent at all. \n\n * Is(pattern)\n Strict equality. The values must match precisely.\n\n * Startswith(pattern)\n Matches if the string starts with the given pattern.\n\n * Endswith(pattern)\n Matches if the string ends with the given pattern\n\n * Contains(pattern)\n Matches if the string contains the given pattern.\n\n * Like(regex)\n Match by a regular expression.\n\n\n\nInstallation\n============\n\nYou can install ``durian`` either via the Python Package Index (PyPI)\nor from source.\n\nTo install using ``pip``,::\n\n $ pip install durian\n\n\nTo install using ``easy_install``,::\n\n $ easy_install durian\n\n\nIf you have downloaded a source tarball you can install it\nby doing the following,::\n\n $ python setup.py build\n # python setup.py install # as root\n\nExamples\n========\n\n.. Please write some examples using your package here.\n\n\nLicense\n=======\n\nBSD License\n\n\nContact\n=======\n\nAsk Solem ", "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/ask/durian/", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "durian", "package_url": "https://pypi.org/project/durian/", "platform": "any", "project_url": "https://pypi.org/project/durian/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/ask/durian/" }, "release_url": "https://pypi.org/project/durian/0.1.0/", "requires_dist": null, "requires_python": null, "summary": "Webhooks for Django **EXPERIMENTAL**", "version": "0.1.0" }, "last_serial": 791442, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "4b0ac2c6be7f709c1a6f26ab6009dcd9", "sha256": "39241a937ea76769142ebd710564c405f1b2c61e692e62d538e497cef3da2076" }, "downloads": -1, "filename": "durian-0.0.1.tar.gz", "has_sig": false, "md5_digest": "4b0ac2c6be7f709c1a6f26ab6009dcd9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21324, "upload_time": "2009-09-10T17:08:04", "url": "https://files.pythonhosted.org/packages/fd/bc/67e6895a3be1f26a4aa2a63eef55a697d05d4c804e26d740bcb88ed3aec1/durian-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "06ccd67bfdc25530a0372175fb6dfbba", "sha256": "a7e72a094453ec2e2cd24a553bbd2bedc55287d4642222015a18f873fd36c139" }, "downloads": -1, "filename": "durian-0.0.2.tar.gz", "has_sig": false, "md5_digest": "06ccd67bfdc25530a0372175fb6dfbba", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140158, "upload_time": "2009-09-11T19:29:03", "url": "https://files.pythonhosted.org/packages/a4/d2/ce54b30d0e2f9ca53cbdeac97508b7eb296f1438d6bac908ef230ff4643b/durian-0.0.2.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "32ac3b5d8f3135ad25b660b7421bdea9", "sha256": "8d663ba763a6421077c2bef4196966aeee08efaacba5b320238ab44bb9a300cc" }, "downloads": -1, "filename": "durian-0.1.0.tar.gz", "has_sig": false, "md5_digest": "32ac3b5d8f3135ad25b660b7421bdea9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 141931, "upload_time": "2009-09-12T16:49:21", "url": "https://files.pythonhosted.org/packages/fb/46/158e90ff0e9e0efad0315a50a2161ee8811fce0a49c7972fc1f71fc2738a/durian-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "32ac3b5d8f3135ad25b660b7421bdea9", "sha256": "8d663ba763a6421077c2bef4196966aeee08efaacba5b320238ab44bb9a300cc" }, "downloads": -1, "filename": "durian-0.1.0.tar.gz", "has_sig": false, "md5_digest": "32ac3b5d8f3135ad25b660b7421bdea9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 141931, "upload_time": "2009-09-12T16:49:21", "url": "https://files.pythonhosted.org/packages/fb/46/158e90ff0e9e0efad0315a50a2161ee8811fce0a49c7972fc1f71fc2738a/durian-0.1.0.tar.gz" } ] }