{ "info": { "author": "Adam Hooper", "author_email": "adam@adamhooper.com", "bugtrack_url": null, "classifiers": [], "description": "channels_rabbitmq\n=================\n\nA Django Channels channel layer that uses RabbitMQ as its backing store.\n\nInstallation\n------------\n\n``pip install channels_rabbitmq``\n\nUsage\n-----\n\nThen set up the channel layer in your Django settings file like so::\n\n CHANNEL_LAYERS = {\n \"default\": {\n \"BACKEND\": \"channels_rabbitmq.core.RabbitmqChannelLayer\",\n \"CONFIG\": {\n \"host\": \"amqp://guest:guest@127.0.0.1/asgi\",\n # \"ssl_context\": ... (optional)\n },\n },\n }\n\nPossible options for ``CONFIG`` are listed below.\n\n``host``\n~~~~~~~~\n\nURL of the server to connect to, adhering to `RabbitMQ spec\n`_. To connect to a RabbitMQ cluster,\nuse a DNS server to resolve a hostname to multiple IP addresses.\nchannels_rabbitmq will automatically reconnect if at least one of them is\nreachable in case of a disconnection.\n\n``expiry``\n~~~~~~~~~~\n\nMinimum number of seconds a message should wait in a RabbitMQ queue, before it\nmay be silently dropped.\n\nDefaults to ``60``. You generally shouldn't need to change this, but you may\nwant to turn it down if you have peaky traffic you wish to drop, or up if you\nhave peaky traffic you want to backlog until you get to it.\n\n``group_expiry``\n~~~~~~~~~~~~~~~~\n\nGroup expiry in seconds. Defaults to ``86400``. Channels will be removed from\nthe group after this amount of time. It's recommended that you increase this\nparameter to ``86400000`` (1 year) and rely on explicit ``group_discard()`` to\ncancel subscriptions. (If your process halts, the group membership will\ndisappear from RabbitMQ immediately: you needn't worry about leaks.)\n\n``local_capacity``\n~~~~~~~~~~~~~~~~~~\n\nNumber of messages queued in memory. Defaults to ``100``. (A message sent to\na group with two channels counts as two messages.) When ``local_capacity``\nmessages are queued, the message backlog will grow on RabbitMQ.\n\n``local_expiry``\n~~~~~~~~~~~~~~~~\n\nMinimum number of seconds a message received from RabbitMQ must be held in\nmemory waiting for ``receive()``, before it may be dropped. Defaults to\n``expiry``.\n\nA warning will be logged when a message expires locally. The warning can\nindicate that a channel has more messages than it can handle; or that\nmessages are being sent to a channel that does not exist. (Perhaps a missing\nchannel was implied by ``group_add()``, and a matching ``group_discard()``\nwas never called.)\n\n``remote_capacity``\n~~~~~~~~~~~~~~~~~~~\n\nNumber of messages stored on RabbitMQ for each client. Defaults to ``100``.\n(A message sent to a group with three channels on two distinct clients counts\nas two messages.) When ``remote_capacity`` messages are queued in RabbitMQ,\nthe channel will refuse new messages. Calls from any client to ``send()`` or\n``group_send()`` to the at-capacity client will raise ``ChannelFull``.\n\n``prefetch_count``\n~~~~~~~~~~~~~~~~~~\n\nNumber of messages to read from RabbitMQ at a time. Defaults to ``10``. This\nmakes ``local_capacity`` a bit of a \"loose\" setting: if messages are queued\nrapidly enough, the client may request ``prefetch_count`` messages even if it\nalready has ``local_capacity - 1`` messages in memory. Higher settings\naccelerate throughput a little bit; lower settings help adhere to\n``local_capacity`` more rigorously.\n\n``ssl_context``\n~~~~~~~~~~~~~~~\n\nAn `SSL context\n`_. Changes the\ndefault ``host`` port to 5671 (instead of 5672).\n\nFor instance, to connect to an TLS RabbitMQ service that will verify your\nclient::\n\n import ssl\n ssl_context = ssl.create_default_context(\n cafile=str(Path(__file__).parent.parent / 'ssl' / 'server.cert'),\n )\n ssl_context.load_cert_chain(\n certfile=str(Path(__file__).parent.parent / 'ssl' / 'client.certchain'),\n keyfile=str(Path(__file__).parent.parent / 'ssl' / 'client.key'),\n )\n CHANNEL_LAYERS['default']['CONFIG']['ssl_context'] = ssl_context\n\nBy default, there is no SSL context; all messages (and passwords) are\nare transmitted in cleartext.\n\n``groups_exchange``\n~~~~~~~~~~~~~~~~~~~\n\nGlobal direct exchange name used by channels to exchange group messages.\nDefaults to ``\"groups\"``. See also `Design decisions`_.\n\nDesign decisions\n----------------\n\nTo scale enormously, this layer only creates one RabbitMQ queue per instance.\nThat means one web server gets one RabbitMQ queue, no matter how many\nwebsocket connections are open. For each message being sent, the client-side\nlayer determines the RabbitMQ queue name and uses it as the routing key.\n\nGroups are implemented using a single, global RabbitMQ direct exchange called\n\"groups\" by default. To send a message to a group, the layer sends the message to the\n\"groups\" exchange with the group name as the routing key. The client binds and\nunbinds during ``group_add()`` and ``group_remove()`` to ensure messages for\nany of its groups will reach it. See also the `groups_exchange`_ option.\n\nRabbitMQ queues are ``exclusive``: when a client disconnects (through close or\ncrash), RabbitMQ will delete the queue and unbind the groups.\n\nDjango Channels' specification does not account for \"connecting\" and\n\"disconnecting\", so this layer is always connected. It will reconnect forever\nin the event loop's background, logging warnings each time the connect fails.\n\nOnce a connection has been created, it pollutes the event loop so that\n``async_to_sync()`` will destroy the connection if it was created within\n``async_to_sync()``. Each connection starts a background async loop that pulls\nmessages from RabbitMQ and routes them to receiver queues; each ``receive()``\nqueries receiver queues. Empty queues are deleted. TODO delete queues that\nonly contain expired messages, so we don't leak when sending to dead channels.\n\nDependencies\n------------\n\nYou'll need Python 3.6+ (lower hasn't been tested) and a RabbitMQ server.\n\nIf you have Docker, here's how to start a development server::\n\n ssl/prepare-certs.sh # Create SSL certificates used in tests\n docker run --rm -it \\\n -p 5671:5671 \\\n -p 5672:5672 \\\n -p 15672:15672 \\\n -v \"/$(pwd)\"/ssl:/ssl \\\n -e RABBITMQ_SSL_CACERTFILE=/ssl/ca.cert \\\n -e RABBITMQ_SSL_CERTFILE=/ssl/server.cert \\\n -e RABBITMQ_SSL_KEYFILE=/ssl/server.key \\\n -e RABBITMQ_SSL_VERIFY=verify_peer \\\n -e RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT=true \\\n rabbitmq:3.7.8-management-alpine\n\nYou can access the RabbitMQ management interface at http://localhost:15672.\n\nContributing\n------------\n\nTo add features and fix bugs\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFirst, start a development RabbitMQ server::\n\n ssl/prepare-certs.sh # Create SSL certificates used in tests\n docker run --rm -it \\\n -p 5671:5671 \\\n -p 5672:5672 \\\n -p 15672:15672 \\\n -v \"/$(pwd)\"/ssl:/ssl \\\n -e RABBITMQ_SSL_CACERTFILE=/ssl/ca.cert \\\n -e RABBITMQ_SSL_CERTFILE=/ssl/server.cert \\\n -e RABBITMQ_SSL_KEYFILE=/ssl/server.key \\\n -e RABBITMQ_SSL_VERIFY=verify_peer \\\n -e RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT=true \\\n rabbitmq:3.7.8-management-alpine\n\nNow take on the development cycle:\n\n#. ``python ./setup.py pytest`` # to ensure tests pass.\n#. Write new tests in ``tests/`` and make sure they fail.\n#. Write new code in ``channels_rabbitmq/`` to make the tests pass.\n#. Submit a pull request.\n\nTo deploy\n~~~~~~~~~\n\nUse `semver `_.\n\n#. Change ``__version__`` in ``channels_rabbitmq/__init__.py``.\n#. Add to ``CHANGELOG.rst``.\n#. ``git commit channels_rabbitmq/__init__.py CHANGELOG.rst -m 'vX.X.X'`` but don't push.\n#. ``git tag vX.X.X``\n#. ``git push --tags && git push``\n\nTravisCI will push to PyPi.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/CJWorkbench/channels_rabbitmq/", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "channels-rabbitmq", "package_url": "https://pypi.org/project/channels-rabbitmq/", "platform": "", "project_url": "https://pypi.org/project/channels-rabbitmq/", "project_urls": { "Homepage": "http://github.com/CJWorkbench/channels_rabbitmq/" }, "release_url": "https://pypi.org/project/channels-rabbitmq/1.1.5/", "requires_dist": null, "requires_python": "", "summary": "RabbitMQ-backed ASGI channel layer implementation", "version": "1.1.5" }, "last_serial": 5716785, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "cdbb0fea2da438c0b907e05e9415b81b", "sha256": "fed0596637c588e90f7902ccae69ac4d5e6b2fbe7f2d6e03a909b67a01627810" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.1.tar.gz", "has_sig": false, "md5_digest": "cdbb0fea2da438c0b907e05e9415b81b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11516, "upload_time": "2018-10-23T19:02:26", "url": "https://files.pythonhosted.org/packages/9e/07/502eb02015bb8f27ce526981c8b62e8ffab0b7331f1894cd4e7d1973ef58/channels_rabbitmq-0.0.1.tar.gz" } ], "0.0.10": [ { "comment_text": "", "digests": { "md5": "2cd7021cbc8ee92d0ba3e706368e0f10", "sha256": "3e1e66ddcead244b764fcc2ce5f0709be643767cad1d0edb4948e09a6ddae4f1" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.10.tar.gz", "has_sig": false, "md5_digest": "2cd7021cbc8ee92d0ba3e706368e0f10", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14508, "upload_time": "2019-02-06T15:15:08", "url": "https://files.pythonhosted.org/packages/fd/8f/8ef715965ba5386ba7833804f14ad0ed47f8d0662305b132f1a51dbfd882/channels_rabbitmq-0.0.10.tar.gz" } ], "0.0.11": [ { "comment_text": "", "digests": { "md5": "18e2dc7700cb77af250703383719face", "sha256": "4069914ebaeb77241db0a1ccfbf80affc543aafae4a5fb5dbd2e81d2851fec45" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.11.tar.gz", "has_sig": false, "md5_digest": "18e2dc7700cb77af250703383719face", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14509, "upload_time": "2019-02-21T21:40:35", "url": "https://files.pythonhosted.org/packages/4b/9c/d2e0e8b55d5af2a62f4a0f4bc7c7d5682950f30dc29b7427ead226bd7480/channels_rabbitmq-0.0.11.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "538f4b7b334673b554afa983572a1674", "sha256": "c0e153892504a7101dd723c0f576024ac767f21adebc60bab2ddb4935baa1997" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.2.tar.gz", "has_sig": false, "md5_digest": "538f4b7b334673b554afa983572a1674", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11585, "upload_time": "2018-10-23T21:46:31", "url": "https://files.pythonhosted.org/packages/3b/70/ecc8ca8a5bf1ac071c7992c7d4ad97706462fbbd8812a6738f91066eb607/channels_rabbitmq-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "372d16d4d27abaf421eb330230480b69", "sha256": "902a5c344b24ab1dd41ecf00c388ad02b561d348d87361e94b64a2b0dadb6880" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.3.tar.gz", "has_sig": false, "md5_digest": "372d16d4d27abaf421eb330230480b69", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12297, "upload_time": "2018-10-24T16:55:23", "url": "https://files.pythonhosted.org/packages/21/44/43a9e9dea80d6dbce82c51108ec64754f1eace632bcab6284ec1fca7f9e0/channels_rabbitmq-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "e095a0c75bda0c204c0f05cdf18360e2", "sha256": "1407d1a1310daf5cdd037f445d08c30e08d4b494e81db9455bbac149c06dd828" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.4.tar.gz", "has_sig": false, "md5_digest": "e095a0c75bda0c204c0f05cdf18360e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12738, "upload_time": "2019-01-31T22:43:18", "url": "https://files.pythonhosted.org/packages/c0/c5/3b77556fe65c27f54bc001046f438fe31bfee0597a9ee3509cb4804c8d54/channels_rabbitmq-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "759fbbe44f281ff25eeae0fba055ab70", "sha256": "467b6e26e4ea60613a4bccb383ac7edad3f6860123f44a53e0a9fc87cc9686b2" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.5.tar.gz", "has_sig": false, "md5_digest": "759fbbe44f281ff25eeae0fba055ab70", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12738, "upload_time": "2019-02-01T19:19:56", "url": "https://files.pythonhosted.org/packages/37/19/bd92319e2f20ae42b7c346b1cf9471b53939499c064ee0a282472f7fccce/channels_rabbitmq-0.0.5.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "a923e7ea990bf3add454d1dd2faf87b7", "sha256": "8edacf451c5b24a2400a1a6e5b7c9d3cb80b8f9bd054bdaf839856a2b32b9b92" }, "downloads": -1, "filename": "channels_rabbitmq-0.0.9.tar.gz", "has_sig": false, "md5_digest": "a923e7ea990bf3add454d1dd2faf87b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14465, "upload_time": "2019-02-05T22:07:30", "url": "https://files.pythonhosted.org/packages/98/95/8cedee784d20b2b48cae145abcf284340f5b6aebb724cfc195f2a4d9ce1d/channels_rabbitmq-0.0.9.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "5a75114d091d25acdda3e92c39c47795", "sha256": "18b62d1ef830a7021bf24acdbfafaa7a8acfcaad16d0ed82213d3fa22e08929f" }, "downloads": -1, "filename": "channels_rabbitmq-1.0.0.tar.gz", "has_sig": false, "md5_digest": "5a75114d091d25acdda3e92c39c47795", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14541, "upload_time": "2019-04-24T15:37:30", "url": "https://files.pythonhosted.org/packages/7f/78/4ebb1027d9845814e7d00c6311e46bdba95d0fcf8c9026284ec42d0d9762/channels_rabbitmq-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "8d2c9c972f9d7e60dc0307d56a15004c", "sha256": "ced2786bb65bc2c5ff13f1c05d6991a8520334e7a79b95d81e21b14e21e8189c" }, "downloads": -1, "filename": "channels_rabbitmq-1.0.1.tar.gz", "has_sig": false, "md5_digest": "8d2c9c972f9d7e60dc0307d56a15004c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14606, "upload_time": "2019-05-06T15:46:29", "url": "https://files.pythonhosted.org/packages/78/07/e969ac4ab432312f592d082a77ad62851b6327402820566d5109925416a4/channels_rabbitmq-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "ebe35798840686c159631bfd24dee268", "sha256": "eef8a89fb7caf1c0ebf81e0d0d63e5655c396f28511d511791f953957bb1114f" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.0.tar.gz", "has_sig": false, "md5_digest": "ebe35798840686c159631bfd24dee268", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15671, "upload_time": "2019-05-09T21:58:36", "url": "https://files.pythonhosted.org/packages/3f/d6/4daeac98d4f29568a973dd8db9976a349dee518b18a56e5d47e6d8d1e82c/channels_rabbitmq-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "fc731f744ae1dac9237a71b2200ba760", "sha256": "a967b77dc71435634e15ee8b65ba4dc0ac241fb9016bf85b614b85c8182b42b2" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.1.tar.gz", "has_sig": false, "md5_digest": "fc731f744ae1dac9237a71b2200ba760", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16074, "upload_time": "2019-05-23T18:24:22", "url": "https://files.pythonhosted.org/packages/cb/fc/80dde1595ac89eb7ced85fdce593ce97e5c32b5a3a96e11dadc9e8bb76bd/channels_rabbitmq-1.1.1.tar.gz" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "b64c489fbc97753d8f799d6f8d6035a5", "sha256": "b1dcc8751e12246c66fe4480f62dcd24f84f0010e5c5e03d093215414b4ba80f" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.2.tar.gz", "has_sig": false, "md5_digest": "b64c489fbc97753d8f799d6f8d6035a5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16204, "upload_time": "2019-06-10T21:18:24", "url": "https://files.pythonhosted.org/packages/f5/ed/2d7941410d043e3465bc3ec9abaa44e5b5537cc03eda69d7d05dac8a8b1b/channels_rabbitmq-1.1.2.tar.gz" } ], "1.1.3": [ { "comment_text": "", "digests": { "md5": "eba7b822bd16769726ada2c2a42f3606", "sha256": "f1f6801497a70a1a857d8f5cc1c84fbb56be81fc26cfe6ec069c87e82b17e0de" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.3.tar.gz", "has_sig": false, "md5_digest": "eba7b822bd16769726ada2c2a42f3606", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17954, "upload_time": "2019-06-16T19:26:55", "url": "https://files.pythonhosted.org/packages/23/05/9ff094ce3aba57c0e5ed78ae53024588b7ef07caf6338f292444dfff3389/channels_rabbitmq-1.1.3.tar.gz" } ], "1.1.4": [ { "comment_text": "", "digests": { "md5": "81dae3a17cde2f5f332ae500756ca9e2", "sha256": "d4c10a4ed7c3c4cf98fe31f49157c943a86aef52d0f405d22d3f54bf9b67dc82" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.4.tar.gz", "has_sig": false, "md5_digest": "81dae3a17cde2f5f332ae500756ca9e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18049, "upload_time": "2019-07-09T16:25:40", "url": "https://files.pythonhosted.org/packages/a0/ad/9596ac9c839c167c8b30143099e087e104c2dc8dba9fe534ae6dbe5a649e/channels_rabbitmq-1.1.4.tar.gz" } ], "1.1.5": [ { "comment_text": "", "digests": { "md5": "c729ab0e7cd965332c46b94f4310a28e", "sha256": "f9e16f2d8c6ffccb6184d4db13181c3bcbbe8cec0e126d63e4b65bcf4a2d1fbe" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.5.tar.gz", "has_sig": false, "md5_digest": "c729ab0e7cd965332c46b94f4310a28e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18044, "upload_time": "2019-08-22T18:51:35", "url": "https://files.pythonhosted.org/packages/43/18/e6bb3eed3b8c44be823b38cb21a1ca3292c4dbab0b5e99c50807eb3c47aa/channels_rabbitmq-1.1.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c729ab0e7cd965332c46b94f4310a28e", "sha256": "f9e16f2d8c6ffccb6184d4db13181c3bcbbe8cec0e126d63e4b65bcf4a2d1fbe" }, "downloads": -1, "filename": "channels_rabbitmq-1.1.5.tar.gz", "has_sig": false, "md5_digest": "c729ab0e7cd965332c46b94f4310a28e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18044, "upload_time": "2019-08-22T18:51:35", "url": "https://files.pythonhosted.org/packages/43/18/e6bb3eed3b8c44be823b38cb21a1ca3292c4dbab0b5e99c50807eb3c47aa/channels_rabbitmq-1.1.5.tar.gz" } ] }