{ "info": { "author": "Matthaus Woolard", "author_email": "matthaus.woolard@gmail.com", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "===================================\nHyper Media Channels Rest Framework\n===================================\n\nA Hyper Media style serializer for DjangoChannelsRestFramework_.\n\n.. image:: https://travis-ci.org/hishnash/hypermediachannels.svg?branch=master\n :target: https://travis-ci.org/hishnash/hypermediachannels\n\nAPI USAGE\n=========\n\nThis is a collection of serialisers and serialiser fields that creats a\nhypermidea style like PK\n\nSetting up your consumers\n-------------------------\n\nAll of your consumers should be mapped through a `AsyncJsonWebsocketDemultiplexer`.\n\n.. code-block:: python\n\n from channelsmultiplexer import AsyncJsonWebsocketDemultiplexer\n from djangochannelsrestframework.generics import GenericAsyncAPIConsumer\n from hypermediachannels.serializers import HyperChannelsApiModelSerializer\n\n class UserSerializer(HyperChannelsApiModelSerializer):\n class Meta:\n model = User\n fields = (\n '@id',\n 'username'\n )\n\n class UserConsumer(GenericAsyncAPIConsumer):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n\n class MainDemultiplexer(AsyncJsonWebsocketDemultiplexer):\n applications = {\n 'users': UserConsumer,\n }\n\nThen when configuring your Channels Application add the ``MainDemultiplexer`` as your main consumer. This way all Websocket connections on that URL will run through the ``Demultiplexer``. See DjangoChannelsRestFramework_ for more deaitls on how to write consumers.\n\n\nHyperChannelsApiModelSerializer\n-------------------------------\n\nThis can be used inplace of the DRF ``ModelSerializer``. It will (if you\ninclude ``@id`` in the ``fields`` list) add a self reference to the\nmodel being displayed)\n\neg ``User`` model Serialiser might respond like this if its fields are\n``('@id', 'username', 'profile')``\n\n.. code:: js\n\n {\n @id: {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 1023\n }\n },\n username: 'bob@example.com',\n profile: {\n stream: 'profile',\n payload: {\n action: 'retrieve',\n pk: 23\n }\n }\n }\n\nThis will under the hood use ``HyperlinkedIdentityField`` to create the\n``@id`` and ``profile`` fields and they will (by default) return these\n``retrieve`` objects.\n\nWhy do we do this.\n~~~~~~~~~~~~~~~~~~\n\nthis means that if we then need to lookup that ``profile`` for this user\nwe can just send the msg:\n\n.. code:: js\n\n {\n stream: 'profile',\n payload: {\n action: 'retrieve',\n pk: 23\n }\n }\n\nDown the websocket and we will get that item, the frontend code does not\nneed to track all of these lockup logic, (consider that some models\nmight have lookup that is not based on ``pk`` for example).\n\nIf you need to define a different set of lookup params. You can use the\n``kwarg_mappings``, ``stream_name`` and ``action_name`` kwargs to\noverride this.\n\neg:\n\n.. code:: python\n\n class UserSerializer(HyperChannelsApiModelSerializer):\n class Meta:\n model = get_user_model()\n fields = (\n '@id', 'username', 'profile'\n )\n\n extra_kwargs = {\n 'profile': {\n 'action_name': 'user_profile',\n 'kwarg_mappings': {\n 'user_pk': 'self.pk',\n 'team_pk': 'team.pk'\n }\n },\n }\n\nthe ``kwarg_mappings`` will set the value in the response ``user_pk`` by\nextracting the ``pk`` value on from the ``User`` instance.\n\n(pre-appending ``self`` to the ``kwarg_mappings`` value means it will do\nthe lookup based on the instance parsed to the parent ``Serializer``\nrather than the instance for this field. In this case a user profile).\n\nso the above would return:\n\n.. code:: js\n\n {\n @id: {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 1023\n }\n },\n username: 'bob@example.com',\n profile: {\n stream: 'user_profile',\n payload: {\n action: 'retrieve',\n user_pk: 1023,\n team_pk: 234234\n }\n }\n }\n\nYou can use ``.`` to access nested values eg. ``profile.team.name``.\n\nAlternatively you can create fields as you would in DRF.\n''''''''''''''''''''''''''''''''''''''''''''''''''''''''\n\n.. code:: python\n\n class UserSerializer(HyperChannelsApiModelSerializer):\n team = HyperChannelsApiRelationField(\n source='profile.team',\n kwarg_mappings={\n 'member_username': 'self.username'\n }\n )\n\n class Meta:\n model = get_user_model()\n fields = (\n '@id', 'username', 'team'\n )\n\nthis will return:\n\n.. code:: js\n\n {\n @id: {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 1023\n }\n },\n username: 'bob@example.com',\n team: {\n stream: 'team',\n payload: {\n action: 'retrieve',\n member_username: 'bob@example.com'\n }\n }\n }\n\nIf you reference a Many field the ``HyperChannelsApiModelSerializer``\nwill do some magic so that:\n\n.. code:: python\n\n class UserSerializer(HyperChannelsApiModelSerializer):\n friends = HyperChannelsApiRelationField(\n source='profile.friends'\n )\n\n class Meta:\n model = get_user_model()\n fields = (\n '@id', 'username', 'friends'\n )\n\n\n\n extra_kwargs = {\n 'friends': {\n 'kwarg_mappings': {\n 'user_pk': 'self.user.pk',\n }\n },\n }\n\nAdding ``extra_kwargs`` for any ``Many`` field can be important so that\nyou can controle the lookup params used.\n\n**NOTE** all ``Many`` fields (forwards and backwards) will extract\nvalues from the parent instance regardless of if you use ``self.`` in\nthe ``kwarg_mappings`` value.)\n\nthis will return:\n\n.. code:: js\n\n {\n @id: {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 1023\n }\n },\n username: 'bob@example.com',\n friends: {\n stream: 'user_profile', payload: {action: 'list', user_pk: 1023}\n }\n }\n\nRemember you can also override the ``@id`` lookup/action and stream if\nneeded, eg:\n\n.. code:: python\n\n extra_kwargs = {\n '@id': {\n 'action_name': 'subscribe_status',\n 'kwarg_mappings': {\n 'username': 'username'\n }\n },\n }\n\nReturning Many items.\n---------------------\n\nExpect to get:\n\n.. code:: js\n\n [\n {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 1023\n }\n },\n {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 234\n }\n },\n {\n stream: 'user',\n payload: {\n action: 'retrieve',\n pk: 103223\n }\n },\n ]\n\nRather than getting a fully expanded value for each instance you will\nrather just get a list of ``hyper media paths`` you can use to lookup\nthe instance you need.\n\nIf you need to override the ``stream`` ``action`` or ``lookup`` do this:\n\n.. code:: python\n\n class UserSerializer(HyperChannelsApiModelSerializer):\n\n class Meta:\n model = User\n fields = (\n '@id',\n 'username'\n )\n\n many_stream_name = 'active_users'\n\n many_kwarg_mappings = {\n 'username': 'username'\n }\n\n many_action_name = 'subscribe'\n\n\n.. _DjangoChannelsRestFramework: https://github.com/hishnash/djangochannelsrestframework\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/hishnash/hypermediachannels", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "hypermediachannels", "package_url": "https://pypi.org/project/hypermediachannels/", "platform": "", "project_url": "https://pypi.org/project/hypermediachannels/", "project_urls": { "Homepage": "https://github.com/hishnash/hypermediachannels" }, "release_url": "https://pypi.org/project/hypermediachannels/0.0.4/", "requires_dist": [ "channels (>=2.1.1)", "Django (>=2.0.0)", "djangochannelsrestframework (==0.0.3)", "channelsmultiplexer (==0.0.2)", "pytest (~=3.7.1); extra == 'tests'", "pytest-django (~=3.4.1); extra == 'tests'", "pytest-asyncio (~=0.9); extra == 'tests'", "coverage (~=4.4); extra == 'tests'" ], "requires_python": "", "summary": "Hyper Media Channels Rest Framework.", "version": "0.0.4" }, "last_serial": 4184148, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "6fe48af2261c2804628b8b40752e5c73", "sha256": "9d6bfb2083e8a447859f91169f66d94de3c5b82413d72990e3e31f758e9fc24b" }, "downloads": -1, "filename": "hypermediachannels-0.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6fe48af2261c2804628b8b40752e5c73", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6541, "upload_time": "2018-05-23T05:28:57", "url": "https://files.pythonhosted.org/packages/7a/04/c4a92e7bc4dfbcd9d13a747604ac44a7900d370544b2ccf5dce676a28670/hypermediachannels-0.0.1-py2.py3-none-any.whl" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "436be866a93229dd2f2e440363bb41be", "sha256": "81876066674e20c29f4b51dc7e48f50db0989b38983d695abc7c73f092493f13" }, "downloads": -1, "filename": "hypermediachannels-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "436be866a93229dd2f2e440363bb41be", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6540, "upload_time": "2018-05-23T05:44:07", "url": "https://files.pythonhosted.org/packages/50/2d/3eeec343f18c02c90dab649f46646aad90eef78b494cdd0802eb3bc7a1ff/hypermediachannels-0.0.2-py2.py3-none-any.whl" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "eef062344abeea20d1cf604d66ceaa76", "sha256": "d2077a92bf7fdef0be1ae7c1b2f02ddd53f401104cb679b999578f6a0fbdbac9" }, "downloads": -1, "filename": "hypermediachannels-0.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "eef062344abeea20d1cf604d66ceaa76", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6869, "upload_time": "2018-08-19T00:04:01", "url": "https://files.pythonhosted.org/packages/99/4a/c5ba17b562f4f29da1692cb1f098be5726beef851dde623c0a7e6f3fd7d7/hypermediachannels-0.0.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "38ecb0db9d40ccb77f456b010900f94e", "sha256": "71d4af6ade143fabaf470766e90e1eee3eb4abc2d525652f59e67695bade2199" }, "downloads": -1, "filename": "hypermediachannels-0.0.4.tar.gz", "has_sig": false, "md5_digest": "38ecb0db9d40ccb77f456b010900f94e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8075, "upload_time": "2018-08-19T00:04:02", "url": "https://files.pythonhosted.org/packages/19/05/73db042a663cd79e55dda013f4b61a6cad5d2560e6088fad0752a4983cbd/hypermediachannels-0.0.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "eef062344abeea20d1cf604d66ceaa76", "sha256": "d2077a92bf7fdef0be1ae7c1b2f02ddd53f401104cb679b999578f6a0fbdbac9" }, "downloads": -1, "filename": "hypermediachannels-0.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "eef062344abeea20d1cf604d66ceaa76", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6869, "upload_time": "2018-08-19T00:04:01", "url": "https://files.pythonhosted.org/packages/99/4a/c5ba17b562f4f29da1692cb1f098be5726beef851dde623c0a7e6f3fd7d7/hypermediachannels-0.0.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "38ecb0db9d40ccb77f456b010900f94e", "sha256": "71d4af6ade143fabaf470766e90e1eee3eb4abc2d525652f59e67695bade2199" }, "downloads": -1, "filename": "hypermediachannels-0.0.4.tar.gz", "has_sig": false, "md5_digest": "38ecb0db9d40ccb77f456b010900f94e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8075, "upload_time": "2018-08-19T00:04:02", "url": "https://files.pythonhosted.org/packages/19/05/73db042a663cd79e55dda013f4b61a6cad5d2560e6088fad0752a4983cbd/hypermediachannels-0.0.4.tar.gz" } ] }