{ "info": { "author": "Matthew Dietz, Monsyne Dragon", "author_email": "matthew.dietz@gmail.com, mdragon@rackspace.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 2.6" ], "description": "# Yagi\n\nA modular OpenStack notification event processor/broadcaster written in Python.\n\nYagi is designed to efficiently gather amqp messages in the json format \nused by OpenStack projects notification busses, from a large and \nconfigurable number of queues, and proccess them through an extensible\nset of simple handlers.\n\nHandlers are simple to write, and can be chained in a WSGI-like architecture.\nYagi handles fetching messages, a batch at a time, and passes fetched \nmessages to each handler, handling AMQP message semantics so the handlers \ncan concentrate on the task at hand.\n\nIn addition, a feed daemon is included that can generate a paged Atom feed \nof notification events that have been persisted in a datastore.\n\n## Available Handlers\n\n* AtomPub: Formats notifications in Atom format, and pushes them to a\n feed server using the AtomPub protocol. Useful with feed \n servers such as AtomHopper (http://atomhopper.org/)\n* Redis: Persists notifications to a Redis database. Can be used with\n Yagi\\'s feed daemon.\n* PubSubHubub: Pings a pubsubhubub hub when notifications arrive.\n Together with a hub, and yagi\\'s feed daemon, this can \n enable publish/subscribe subscriptions to notification events.\n* StackTackPing: Works with the StackTach openstack monitoring tool to\n monitor event feeds. If you are using Yagi to provide \n feeds of openstack notifications, this will ping\n stacktach when those feeds are updated, informing it \n of the success or failure of the updates, letting you \n catch if the feed server is down, or some system is \n dropping events.\n\n## Installation and running\n\nThe current version of Yagi can be fetched from the code repository \nat: https://github.com/rackerlabs/yagi \n\ncd to the yagi directory and run:\n\n sudo python setup.py install\n\nThe launch the yagi process:\n\n yagi-event\n\nAn altername config file may be passed to yagi like this:\n\n yagi-event -c /path/to/config/file\n\nYagi does not daemonize. use your favorite daemon manager to do that.\n\n\n## Configuration\n\nA sample yagi.conf can be found in the etc directory.\n\nSections to note:\n* rabbit_broker: Your rabbit connection info goes here.\n* event_feed: If using the feed daemon, remember to set the feed_host to\n the name of the host it is running on. This allows yagi \n to correctly construct links in the feed.\n* persistence: If using the redis handler, put your reddisc connection\n info here.\n* consumers: the 'queues' config variable lists the queues yagi should\n listen on.\n* consumer:$queue_name: For each queue Yagi is listening on there should\n be a consumer section in the config file \n (for example if you have a queue named\n some.queue listed in the [consumers] section, \n there should be a [consumer:some.queue]\n section with configuration for that specific queue.) \n This should list properties\n for the queue, such as if itshould be durable. \n Important variables here are 'apps',\n which is a comma separated list of handlers that \n messages from that queues should be\n passed to, and 'max_messages' which is the maximum \n number of messages that Yagi will pull from that \n queue at one time. (it will then go to the next queue,\n eventually coming back around, if there are still \n messages waiting)\n\nHandlers may also have their own, additional configuration.\nThis is usually found in a section named after the handler (all \nlowercase, one word)\n\n## Scaling\n\nYagi is designed to scale by running multiple processes. Simply \nlaunch as many yagi-event processes as\nyou need to handle your load. (yagi-event is fairly lightweight)\n\n## Dependencies:\n\n* anyjson\n* argparse\n* feedgenerator\n* httplib2\n* requests (eventually httplib2 will be replaced with requests)\n* redis (if using redis handler)\n* webob\n* eventlet\n* python-dateutil\n* daemon\n* pubsubhubbub_publish (if using pubsubhubub handler) (available under \n the publisher_clients folder after checking out the project from \n [Google Code](http://code.google.com/p/pubsubhubbub/source/checkout)\n NOTE: the plan is to replace this dependency later with our implementation\n* carrot (if using Rabbit)\n* routes\n\n## Running the feed daemon\n\nSimply run:\n yagi-feed\n\n## Setting up a hub (if using PubSubHubub)\n\nDownload the Google App Engine SDK for Linux and add it to your path\n\n http://code.google.com/appengine/downloads.html\n\nThen checkout the reference hub.\n\n svn checkout http://pubsubhubbub.googlecode.com/svn/trunk/ pubsubhubbub-read-only\n\nInstall pubsubhubbub_publisher for python\n\n cd pubsubhubbub-read-only/publisher_clients/python\n sudo python setup.py install\n\nStart the hub\n\n cd pubsubhubbub-read-only\n dev_appserver.py hub/ -p\n\n## Testing subscriptions for PubSubHubub.\n\n cd yagi\n\n # You'll want to run this in multiple screen windows or terminal \n # sessions, as the callback process won't daemonize\n\n python subscriber/callback.py \n python subscriber/sub.py \n\n # I usually load other/push_rabbit.py in an iPython session\n cd other\n ipython\n import push_rabbit\n\n # the cast below is assuming you setting up yagi to listen \n # on a queue named 'notifications.warn'\n push_rabbit.cast(dict(a=3), 'instance', 'notifications', 'warn')\n\nYou should see XML content being pushed to your window running \ncallback.py, above.\n\n## Brokers, Consumers and Handlers(Apps)\n\nThe top-level object for Yagi is the Event Broker, which is defined in the \nconfiguration file as:\n\n [event_worker]\n event_driver = yagi.broker.rabbit.Broker\n\nThe Broker will create a Consumer object for each input queue defined. \n\n [consumers]\n queues = queue1, queue2\n\n [consumer:queue1]\n apps = yagi.handler.handler1, myhandlers.handler\n routing_key = notifications.warn\n\n [consumer:queue2]\n apps = ...\n\nThe Consumer grabs the notifications as they come in and give them to the \nhandlers for processing. Handlers are also known as apps for legacy reasons.\nHandlers are chained together, and it's the responability of the handler\nto call child handlers if they think it's appropriate (the default behavior). \nHowever, some handler may wish to kill the chain on an error some other \ncondition. Each handler also gets to process the messages themself. First\nnotifications are checked against the filter list for that handler and, if\naccepted, the `handle_messages()` method is called. Child handlers always get\ncalled unfiltered. \n\n [filters]\n cufpub = compute.instance.exists.verified,compute.instance.exists\n\nCurrently, filters are applied to all handlers, but this should change to\na per-handler filter list. \n\nLook at `yagi.handlers.__init__.py` for details.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rackerlabs/yagi", "keywords": "PubSubHubBub notifications events ATOM RSS", "license": "Apache License (2.0)", "maintainer": null, "maintainer_email": null, "name": "yagi", "package_url": "https://pypi.org/project/yagi/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/yagi/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/rackerlabs/yagi" }, "release_url": "https://pypi.org/project/yagi/0.23/", "requires_dist": null, "requires_python": null, "summary": "A PubSubHubBub Publisher and ATOM feed generator that can consume events from multiple input sources and publish them to standard PSHB hubs", "version": "0.23" }, "last_serial": 1534152, "releases": { "0.13": [ { "comment_text": "", "digests": { "md5": "0e04c939eedbb12a49d07dc45436d388", "sha256": "7d8c52ccd54170ef6d92e7e704cbac2a789ffb794df8280fc37831e24c7d5f0d" }, "downloads": -1, "filename": "yagi-0.13.tar.gz", "has_sig": false, "md5_digest": "0e04c939eedbb12a49d07dc45436d388", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40699, "upload_time": "2015-02-17T22:28:46", "url": "https://files.pythonhosted.org/packages/65/c7/e8aa1712eb030bfa579cab20aaafe83a87f040aa0ab34694220c1182e05b/yagi-0.13.tar.gz" } ], "0.14": [ { "comment_text": "", "digests": { "md5": "f38fabf1224cbe9d9f60753fde5fb715", "sha256": "b3d38b84c7413962fe659d9c11e82e7ebc415d4731bd904ef3a5ff64bc11c45e" }, "downloads": -1, "filename": "yagi-0.14.tar.gz", "has_sig": false, "md5_digest": "f38fabf1224cbe9d9f60753fde5fb715", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40671, "upload_time": "2015-02-17T22:31:54", "url": "https://files.pythonhosted.org/packages/ad/20/dd151a21b4225811b8130919049c7747c811025ebfd7153c804e35ec349c/yagi-0.14.tar.gz" } ], "0.15": [ { "comment_text": "", "digests": { "md5": "76d4e82b64e71b297a973aa24d8f47ed", "sha256": "600c902a4aadc7f622229266abc9761fde9b6891c9c11f8d2e88e5c82896b47f" }, "downloads": -1, "filename": "yagi-0.15.tar.gz", "has_sig": false, "md5_digest": "76d4e82b64e71b297a973aa24d8f47ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40676, "upload_time": "2015-02-17T22:48:16", "url": "https://files.pythonhosted.org/packages/2f/19/2a7f08fcc2c3ad026924cb067509576cb39a266f8464684604b513b540cf/yagi-0.15.tar.gz" } ], "0.16": [ { "comment_text": "", "digests": { "md5": "692584898ad8c90d96e12d560981e3dd", "sha256": "5cad93d681e85a0d93b1ea7a70a467a8c7c8536252dd9bb7c9bc7c3467973981" }, "downloads": -1, "filename": "yagi-0.16.tar.gz", "has_sig": false, "md5_digest": "692584898ad8c90d96e12d560981e3dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40797, "upload_time": "2015-02-24T16:10:54", "url": "https://files.pythonhosted.org/packages/95/02/3979597a408facf3cea6b4df306dd3fae21e9e62d08e292c87db7e42e511/yagi-0.16.tar.gz" } ], "0.17": [ { "comment_text": "", "digests": { "md5": "a74344ed3cb2d76808731e017e1d6392", "sha256": "5205c44ce5bb75047aedf41764b724c05797896c75c2f8be0bcf313a7336be58" }, "downloads": -1, "filename": "yagi-0.17.tar.gz", "has_sig": false, "md5_digest": "a74344ed3cb2d76808731e017e1d6392", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41171, "upload_time": "2015-04-01T18:35:12", "url": "https://files.pythonhosted.org/packages/79/6a/cc14d319aeec95bd930ba83208ee3d6c9016877feddc8d096ab7ad6e4fe7/yagi-0.17.tar.gz" } ], "0.18": [ { "comment_text": "", "digests": { "md5": "03b19590454837b4a71535c6162d039e", "sha256": "76b5bd693cbc724ad8398c87ed89ebcdf86b6e9a41939186645a03cbfe79a875" }, "downloads": -1, "filename": "yagi-0.18.tar.gz", "has_sig": false, "md5_digest": "03b19590454837b4a71535c6162d039e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41280, "upload_time": "2015-04-03T18:49:19", "url": "https://files.pythonhosted.org/packages/5e/6a/8e7c5e4c3a53c8e21b475206df79e00f034fa1d80d451b69c2b7d3877d95/yagi-0.18.tar.gz" } ], "0.19": [], "0.20": [ { "comment_text": "", "digests": { "md5": "10ca57805d52f4711fa2d1c30ae8af6a", "sha256": "cbb0ba3817fe85923be3e327e7452c0643e58027c2037cdc4f353ed7d9e44265" }, "downloads": -1, "filename": "yagi-0.20.tar.gz", "has_sig": false, "md5_digest": "10ca57805d52f4711fa2d1c30ae8af6a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41362, "upload_time": "2015-04-06T17:42:21", "url": "https://files.pythonhosted.org/packages/21/97/d67dfc3e73c693ba0d10f067a3e64f6a3ab5500d2aca394e83dc09398d93/yagi-0.20.tar.gz" } ], "0.22": [ { "comment_text": "", "digests": { "md5": "393f78b32ed8b001d5d8f45b134d046e", "sha256": "cafb77d9b3daa9f0dad1c0d943e9d656bcbf96aa9796b5fd53133f226fc92071" }, "downloads": -1, "filename": "yagi-0.22.tar.gz", "has_sig": false, "md5_digest": "393f78b32ed8b001d5d8f45b134d046e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41371, "upload_time": "2015-04-10T18:46:21", "url": "https://files.pythonhosted.org/packages/1a/c3/f0b81b82ed289fefe23319cef282dc37a80dc38768f5214cd2a096b35a3e/yagi-0.22.tar.gz" } ], "0.23": [ { "comment_text": "", "digests": { "md5": "c9d36d57e78fb4e2c2a201faa2d87f9a", "sha256": "6e0f08782f25b90bb201a41ea43cee2801730636f9e954dc18527a699972efa5" }, "downloads": -1, "filename": "yagi-0.23.tar.gz", "has_sig": false, "md5_digest": "c9d36d57e78fb4e2c2a201faa2d87f9a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41649, "upload_time": "2015-04-16T19:14:38", "url": "https://files.pythonhosted.org/packages/6e/b5/d5903694f7f35bc7a0f942ebf585b55873c0f130ffefb12d318907caeb99/yagi-0.23.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c9d36d57e78fb4e2c2a201faa2d87f9a", "sha256": "6e0f08782f25b90bb201a41ea43cee2801730636f9e954dc18527a699972efa5" }, "downloads": -1, "filename": "yagi-0.23.tar.gz", "has_sig": false, "md5_digest": "c9d36d57e78fb4e2c2a201faa2d87f9a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41649, "upload_time": "2015-04-16T19:14:38", "url": "https://files.pythonhosted.org/packages/6e/b5/d5903694f7f35bc7a0f942ebf585b55873c0f130ffefb12d318907caeb99/yagi-0.23.tar.gz" } ] }