{ "info": { "author": "Syrus Akbary", "author_email": "me@syrusakbary.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries" ], "description": "# Relay Library for GraphQL Python\n\nThis is a library to allow the easy creation of Relay-compliant servers using\nthe [GraphQL Python](https://github.com/graphql-python/graphql-core) reference implementation\nof a GraphQL server.\n\n*Note: The code is a __exact__ port of the original [graphql-relay js implementation](https://github.com/graphql/graphql-relay-js)\nfrom Facebook*\n\n[![PyPI version](https://badge.fury.io/py/graphql-relay.svg)](https://badge.fury.io/py/graphql-relay)\n[![Build Status](https://travis-ci.org/graphql-python/graphql-relay-py.svg?branch=master)](https://travis-ci.org/graphql-python/graphql-relay-py)\n[![Coverage Status](https://coveralls.io/repos/graphql-python/graphql-relay-py/badge.svg?branch=master&service=github)](https://coveralls.io/github/graphql-python/graphql-relay-py?branch=master)\n\n## Getting Started\n\nA basic understanding of GraphQL and of the GraphQL Python implementation is needed\nto provide context for this library.\n\nAn overview of GraphQL in general is available in the\n[README](https://github.com/graphql-python/graphql-core/blob/master/README.md) for the\n[Specification for GraphQL](https://github.com/graphql-python/graphql-core).\n\nThis library is designed to work with the \nthe [GraphQL Python](https://github.com/graphql-python/graphql-core) reference implementation\nof a GraphQL server.\n\nAn overview of the functionality that a Relay-compliant GraphQL server should\nprovide is in the [GraphQL Relay Specification](https://facebook.github.io/relay/docs/graphql-relay-specification.html)\non the [Relay website](https://facebook.github.io/relay/). That overview\ndescribes a simple set of examples that exist as [tests](tests) in this\nrepository. A good way to get started with this repository is to walk through\nthat documentation and the corresponding tests in this library together.\n\n## Using Relay Library for GraphQL Python (graphql-core)\n\nInstall Relay Library for GraphQL Python\n\n```sh\npip install \"graphql-core>=2,<3\" # use version 2.x of graphql-core\npip install graphql-relay\n```\n\nWhen building a schema for [GraphQL](https://github.com/graphql-python/graphql-core),\nthe provided library functions can be used to simplify the creation of Relay\npatterns.\n\n### Connections \n\nHelper functions are provided for both building the GraphQL types\nfor connections and for implementing the `resolver` method for fields\nreturning those types.\n\n - `connection_args` returns the arguments that fields should provide when\nthey return a connection type.\n - `connection_definitions` returns a `connection_type` and its associated\n`edgeType`, given a name and a node type.\n - `connection_from_list` is a helper method that takes a list and the\narguments from `connection_args`, does pagination and filtering, and returns\nan object in the shape expected by a `connection_type`'s `resolver` function.\n - `connection_from_promised_list` is similar to `connection_from_list`, but\nit takes a promise that resolves to an array, and returns a promise that\nresolves to the expected shape by `connection_type`.\n - `cursor_for_object_in_connection` is a helper method that takes a list and a\nmember object, and returns a cursor for use in the mutation payload.\n\nAn example usage of these methods from the [test schema](tests/starwars/schema.py):\n\n```python\nship_edge, ship_connection = connection_definitions('Ship', shipType)\n\nfactionType = GraphQLObjectType(\n name='Faction',\n description='A faction in the Star Wars saga',\n fields= lambda: {\n 'id': global_id_field('Faction'),\n 'name': GraphQLField(\n GraphQLString,\n description='The name of the faction.',\n ),\n 'ships': GraphQLField(\n ship_connection,\n description='The ships used by the faction.',\n args=connection_args,\n resolver=lambda faction, _info, **args: connection_from_list(\n [getShip(ship) for ship in faction.ships], args\n ),\n )\n },\n interfaces=[node_interface]\n)\n```\n\nThis shows adding a `ships` field to the `Faction` object that is a connection.\nIt uses `connection_definitions({name: 'Ship', nodeType: shipType})` to create\nthe connection type, adds `connection_args` as arguments on this function, and\nthen implements the resolver function by passing the list of ships and the\narguments to `connection_from_list`.\n\n### Object Identification\n\nHelper functions are provided for both building the GraphQL types\nfor nodes and for implementing global IDs around local IDs.\n\n - `node_definitions` returns the `Node` interface that objects can implement,\nand returns the `node` root field to include on the query type. To implement\nthis, it takes a function to resolve an ID to an object, and to determine\nthe type of a given object.\n - `to_global_id` takes a type name and an ID specific to that type name,\nand returns a \"global ID\" that is unique among all types.\n - `from_global_id` takes the \"global ID\" created by `to_global_id`, and returns\nthe type name and ID used to create it.\n - `global_id_field` creates the configuration for an `id` field on a node.\n - `plural_identifying_root_field` creates a field that accepts a list of\nnon-ID identifiers (like a username) and maps then to their corresponding\nobjects.\n\nAn example usage of these methods from the [test schema](tests/starwars/schema.py):\n\n```python\ndef get_node(global_id, _info):\n type_, id_ = from_global_id(global_id)\n if type_ == 'Faction':\n return getFaction(id_)\n elif type_ == 'Ship':\n return getShip(id_)\n else:\n return None\n\ndef get_node_type(obj, _info):\n if isinstance(obj, Faction):\n return factionType\n else:\n return shipType\n\nnode_interface, node_field = node_definitions(get_node, get_node_type)\n\nfactionType = GraphQLObjectType(\n name= 'Faction',\n description= 'A faction in the Star Wars saga',\n fields= lambda: {\n 'id': global_id_field('Faction'),\n },\n interfaces= [node_interface]\n)\n\nqueryType = GraphQLObjectType(\n name= 'Query',\n fields= lambda: {\n 'node': node_field\n }\n)\n```\n\nThis uses `node_definitions` to construct the `Node` interface and the `node`\nfield; it uses `from_global_id` to resolve the IDs passed in in the implementation\nof the function mapping ID to object. It then uses the `global_id_field` method to\ncreate the `id` field on `Faction`, which also ensures implements the\n`node_interface`. Finally, it adds the `node` field to the query type, using the\n`node_field` returned by `node_definitions`.\n\n### Mutations\n\nA helper function is provided for building mutations with\nsingle inputs and client mutation IDs.\n\n - `mutation_with_client_mutation_id` takes a name, input fields, output fields,\nand a mutation method to map from the input fields to the output fields,\nperforming the mutation along the way. It then creates and returns a field\nconfiguration that can be used as a top-level field on the mutation type.\n\nAn example usage of these methods from the [test schema](tests/starwars/schema.py):\n\n```python\nclass IntroduceShipMutation(object):\n def __init__(self, shipId, factionId, clientMutationId=None):\n self.shipId = shipId\n self.factionId = factionId\n self.clientMutationId = clientMutationId\n\ndef mutate_and_get_payload(_info, shipName, factionId, **_input):\n newShip = createShip(shipName, factionId)\n return IntroduceShipMutation(\n shipId=newShip.id,\n factionId=factionId,\n )\n\nshipMutation = mutation_with_client_mutation_id(\n 'IntroduceShip',\n input_fields={\n 'shipName': GraphQLField(\n GraphQLNonNull(GraphQLString)\n ),\n 'factionId': GraphQLField(\n GraphQLNonNull(GraphQLID)\n )\n },\n output_fields= {\n 'ship': GraphQLField(\n shipType,\n resolver=lambda payload, _info: getShip(payload.shipId)\n ),\n 'faction': GraphQLField(\n factionType,\n resolver=lambda payload, _info: getFaction(payload.factionId)\n )\n },\n mutate_and_get_payload=mutate_and_get_payload\n)\n\nmutationType = GraphQLObjectType(\n 'Mutation',\n fields=lambda: {\n 'introduceShip': shipMutation\n }\n)\n```\n\nThis code creates a mutation named `IntroduceShip`, which takes a faction\nID and a ship name as input. It outputs the `Faction` and the `Ship` in\nquestion. `mutate_and_get_payload` then gets an object with a property for\neach input field, performs the mutation by constructing the new ship, then\nreturns an object that will be resolved by the output fields.\n\nOur mutation type then creates the `introduceShip` field using the return\nvalue of `mutation_with_client_mutation_id`.\n\n## Contributing\n\nAfter cloning this repo, ensure dependencies are installed by running:\n\n```sh\npython setup.py install\n```\n\nAfter developing, the full test suite can be evaluated by running:\n\n```sh\npython setup.py test # Use --pytest-args=\"-v -s\" for verbose mode\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/graphql-python/graphql-relay-py", "keywords": "api graphql protocol rest relay", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "graphql-relay", "package_url": "https://pypi.org/project/graphql-relay/", "platform": "", "project_url": "https://pypi.org/project/graphql-relay/", "project_urls": { "Homepage": "https://github.com/graphql-python/graphql-relay-py" }, "release_url": "https://pypi.org/project/graphql-relay/2.0.0/", "requires_dist": [ "six (>=1.12)", "graphql-core (<3,>=2.2)", "promise (<3,>=2.2)" ], "requires_python": "", "summary": "Relay implementation for Python", "version": "2.0.0" }, "last_serial": 5619586, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "8334fb7ddba15a5547c37be45fb35dfa", "sha256": "c68428dc3d0771b105d5b7fc30dcf865db27184712075889025ea5d52f699901" }, "downloads": -1, "filename": "graphql-relay-0.1.tar.gz", "has_sig": false, "md5_digest": "8334fb7ddba15a5547c37be45fb35dfa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5351, "upload_time": "2015-09-17T17:23:28", "url": "https://files.pythonhosted.org/packages/ed/9c/c5f6625b9dcfc1cfc4b21158f77625106618b1926dab1627d862eddcecaf/graphql-relay-0.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "5c1459172777dd041241710859692c11", "sha256": "e449b54ef51453bde2ed5f26090f0e93c30d6d03b0ae17a18d77d6a15058c76c" }, "downloads": -1, "filename": "graphql-relay-0.1.2.tar.gz", "has_sig": false, "md5_digest": "5c1459172777dd041241710859692c11", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9007, "upload_time": "2015-09-23T04:19:01", "url": "https://files.pythonhosted.org/packages/7b/de/853ccfd8171befbb177cc0442a7b1834a8ecd7959fb4ae8716f552c2c8e1/graphql-relay-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "dec4ebb849daf476a17ead5e17f808c9", "sha256": "678af38093f4153b430c90fc966d578b7d75e10000303057b131d414a14fb6e7" }, "downloads": -1, "filename": "graphql-relay-0.1.3.tar.gz", "has_sig": false, "md5_digest": "dec4ebb849daf476a17ead5e17f808c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9022, "upload_time": "2015-10-07T05:27:26", "url": "https://files.pythonhosted.org/packages/cb/3a/5798a3d037ec452cf64cd57b00e8277ed17613e468dd12d051e4245be55a/graphql-relay-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "0cf996fb7beff0c482b50d351d4b2c3d", "sha256": "3c0ec743abd1ba75bcd14403b481f98683eacdbf4bde703ac23244d90317ffe3" }, "downloads": -1, "filename": "graphql-relay-0.1.4.tar.gz", "has_sig": false, "md5_digest": "0cf996fb7beff0c482b50d351d4b2c3d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9017, "upload_time": "2015-10-08T04:28:39", "url": "https://files.pythonhosted.org/packages/c2/1f/4d56b6ba6bfc33cdf27b746edde62451eb785f273ad54192beb4f0cacb3c/graphql-relay-0.1.4.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "d377e8eb412336b53baec32d98711ab4", "sha256": "5595ff87db60a89d0d4628d9f2f406682ffb157ea0834f399800f125e39bbccc" }, "downloads": -1, "filename": "graphql-relay-0.2.0.tar.gz", "has_sig": false, "md5_digest": "d377e8eb412336b53baec32d98711ab4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9054, "upload_time": "2015-10-10T07:07:48", "url": "https://files.pythonhosted.org/packages/bf/d4/9b003332ab249075f704d6e1dca39b9eb714636b83a5d26439b4cd339769/graphql-relay-0.2.0.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "79d32339e751025c0b2c12faa4d4b8b6", "sha256": "78619da97851ded699a3bb46c4118780daa87ef328c3296364c1acc16744881d" }, "downloads": -1, "filename": "graphql-relay-0.3.3.tar.gz", "has_sig": false, "md5_digest": "79d32339e751025c0b2c12faa4d4b8b6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9175, "upload_time": "2015-10-21T04:30:48", "url": "https://files.pythonhosted.org/packages/71/d5/a1251273fe9ffae5b7c4b747905995edf76c122dfa90bfef2192980ff96e/graphql-relay-0.3.3.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "782bcbe824c119d7ebee479d5d0da311", "sha256": "ad48eee194038dcf6e4fabca0374bab123017d3820da8c41f5fd82e61fb08825" }, "downloads": -1, "filename": "graphql-relay-0.4.1.tar.gz", "has_sig": false, "md5_digest": "782bcbe824c119d7ebee479d5d0da311", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9371, "upload_time": "2016-05-12T07:25:03", "url": "https://files.pythonhosted.org/packages/31/5e/38e4098b022041d6bc2c9c779d841e8677f957a64735de0d10a092750962/graphql-relay-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "7bf4f2fdad2d941a3d189941ec0867c1", "sha256": "fca2b946c93a1ba1477b3ca261fbef41abd5a257b1ea49d6d8a3f5a495b2792f" }, "downloads": -1, "filename": "graphql-relay-0.4.2.tar.gz", "has_sig": false, "md5_digest": "7bf4f2fdad2d941a3d189941ec0867c1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9383, "upload_time": "2016-05-19T05:10:50", "url": "https://files.pythonhosted.org/packages/02/96/3ffeeeccb60c2208432b078194a5ed0fc9f11dcac45d85d8b23da9c4d9af/graphql-relay-0.4.2.tar.gz" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "e1185297e1f4bbd7cdb1d7313e128e2d", "sha256": "dbc5aedd1a1413ecc3c562b781c46fa7d7d91fb28343844097c898a8d78c74f4" }, "downloads": -1, "filename": "graphql-relay-0.4.3.tar.gz", "has_sig": false, "md5_digest": "e1185297e1f4bbd7cdb1d7313e128e2d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9412, "upload_time": "2016-06-15T06:56:24", "url": "https://files.pythonhosted.org/packages/c8/9a/9f79f262a14bd49549ffe71dd27a3037649161faac276b77166adcc7ddc5/graphql-relay-0.4.3.tar.gz" } ], "0.4.4": [ { "comment_text": "", "digests": { "md5": "62b57f20a7b62a2b7cc77cef68d36dec", "sha256": "b12f37967d118f861d016650c9838bd38cbf9c3b2c882d1e6b5276a8bd4a9913" }, "downloads": -1, "filename": "graphql-relay-0.4.4.tar.gz", "has_sig": false, "md5_digest": "62b57f20a7b62a2b7cc77cef68d36dec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9434, "upload_time": "2016-06-18T19:44:11", "url": "https://files.pythonhosted.org/packages/cf/dc/684ded66cab738f54907d3adc21ea8cc4bf395802c950e2709e36fc43a99/graphql-relay-0.4.4.tar.gz" } ], "0.4.5": [ { "comment_text": "", "digests": { "md5": "1d20e070f039229063c948ef9d8889a6", "sha256": "2716b7245d97091af21abf096fabafac576905096d21ba7118fba722596f65db" }, "downloads": -1, "filename": "graphql-relay-0.4.5.tar.gz", "has_sig": false, "md5_digest": "1d20e070f039229063c948ef9d8889a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9422, "upload_time": "2016-11-23T17:43:40", "url": "https://files.pythonhosted.org/packages/5e/b0/b91fadc180544fc9e3c156d7049561fd5f1e2211d26fd29033548fd50934/graphql-relay-0.4.5.tar.gz" } ], "0.4b1": [ { "comment_text": "", "digests": { "md5": "fe725e899d5926982a550cb4e1d85efc", "sha256": "f7ee771aa9dd4ce80f605a7c80e354b2c3ac2ba0ad3cebe1460204b9dc704e5a" }, "downloads": -1, "filename": "graphql-relay-0.4b1.tar.gz", "has_sig": false, "md5_digest": "fe725e899d5926982a550cb4e1d85efc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9364, "upload_time": "2016-05-12T05:36:26", "url": "https://files.pythonhosted.org/packages/1c/ea/79682a9f969e8d320665623ccc19d48aa6f1e290038f112b3c28726f7cf8/graphql-relay-0.4b1.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "55c988f2b4235e8e8a81a03eb3e00acf", "sha256": "0e94201af4089e1f81f07d7bd8f84799768e39d70fa1ea16d1df505b46cc6335" }, "downloads": -1, "filename": "graphql_relay-2.0.0-py2-none-any.whl", "has_sig": false, "md5_digest": "55c988f2b4235e8e8a81a03eb3e00acf", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 19690, "upload_time": "2019-07-15T19:00:17", "url": "https://files.pythonhosted.org/packages/38/c3/b8e7ceb54d63c908a3176fdab6aec01fecfbac3cd0cf96f825d1a46d5b14/graphql_relay-2.0.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e39f5082051a5ca36ba2cf938b6a75d5", "sha256": "75aa0758971e252964cb94068a4decd472d2a8295229f02189e3cbca1f10dbb5" }, "downloads": -1, "filename": "graphql_relay-2.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e39f5082051a5ca36ba2cf938b6a75d5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 20513, "upload_time": "2019-07-14T23:47:46", "url": "https://files.pythonhosted.org/packages/85/52/0242f2d01a3b925bc200928a2a88925b915b88efcb31c67e966991aa4dee/graphql_relay-2.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6729992ee82e44f53813ea5a9e417e40", "sha256": "7fa74661246e826ef939ee92e768f698df167a7617361ab399901eaebf80dce6" }, "downloads": -1, "filename": "graphql-relay-2.0.0.tar.gz", "has_sig": false, "md5_digest": "6729992ee82e44f53813ea5a9e417e40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12552, "upload_time": "2019-07-15T19:30:46", "url": "https://files.pythonhosted.org/packages/a0/83/bea0cd12b51e1459d6702b0975d2f42ae4607021f22ec90c50b03c397fcc/graphql-relay-2.0.0.tar.gz" } ], "3.0.0a0": [ { "comment_text": "", "digests": { "md5": "edc35ab9ce1517854fd024972a6b328c", "sha256": "8cd27209ed22e29dba7ac42dfbe2ee6c9d71f6826333d87e3d22fd547e72667f" }, "downloads": -1, "filename": "graphql-relay-3.0.0a0.tar.gz", "has_sig": false, "md5_digest": "edc35ab9ce1517854fd024972a6b328c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4", "size": 37591, "upload_time": "2019-07-28T18:13:38", "url": "https://files.pythonhosted.org/packages/19/84/5ce0b983d5c731f5da90494fd9acd4b31d65628d9d07421010f371cfaef5/graphql-relay-3.0.0a0.tar.gz" } ], "3.0.0a1": [ { "comment_text": "", "digests": { "md5": "b89a1e19e262d441ed020a020c1b2283", "sha256": "0f6aee750bf64f8cf6f83f76428d78426f12f7666ee7ba8e6b12ff7b8422cd39" }, "downloads": -1, "filename": "graphql-relay-3.0.0a1.tar.gz", "has_sig": false, "md5_digest": "b89a1e19e262d441ed020a020c1b2283", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4", "size": 38641, "upload_time": "2019-08-01T16:15:52", "url": "https://files.pythonhosted.org/packages/b3/e9/f746793c405695c6c3d2fe023dd19738d1eef20ecdd50ebb9e240b2f6cfc/graphql-relay-3.0.0a1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "55c988f2b4235e8e8a81a03eb3e00acf", "sha256": "0e94201af4089e1f81f07d7bd8f84799768e39d70fa1ea16d1df505b46cc6335" }, "downloads": -1, "filename": "graphql_relay-2.0.0-py2-none-any.whl", "has_sig": false, "md5_digest": "55c988f2b4235e8e8a81a03eb3e00acf", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 19690, "upload_time": "2019-07-15T19:00:17", "url": "https://files.pythonhosted.org/packages/38/c3/b8e7ceb54d63c908a3176fdab6aec01fecfbac3cd0cf96f825d1a46d5b14/graphql_relay-2.0.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e39f5082051a5ca36ba2cf938b6a75d5", "sha256": "75aa0758971e252964cb94068a4decd472d2a8295229f02189e3cbca1f10dbb5" }, "downloads": -1, "filename": "graphql_relay-2.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e39f5082051a5ca36ba2cf938b6a75d5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 20513, "upload_time": "2019-07-14T23:47:46", "url": "https://files.pythonhosted.org/packages/85/52/0242f2d01a3b925bc200928a2a88925b915b88efcb31c67e966991aa4dee/graphql_relay-2.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6729992ee82e44f53813ea5a9e417e40", "sha256": "7fa74661246e826ef939ee92e768f698df167a7617361ab399901eaebf80dce6" }, "downloads": -1, "filename": "graphql-relay-2.0.0.tar.gz", "has_sig": false, "md5_digest": "6729992ee82e44f53813ea5a9e417e40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12552, "upload_time": "2019-07-15T19:30:46", "url": "https://files.pythonhosted.org/packages/a0/83/bea0cd12b51e1459d6702b0975d2f42ae4607021f22ec90c50b03c397fcc/graphql-relay-2.0.0.tar.gz" } ] }