{ "info": { "author": "Gustavo Sverzut Barbieri", "author_email": "barbieri@profusion.mobi", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: ISC License (ISCL)", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Utilities" ], "description": "`sgqlc` - Simple GraphQL Client\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. image:: https://travis-ci.com/profusion/sgqlc.svg?branch=master\n :target: https://travis-ci.com/profusion/sgqlc\n\n.. image:: https://coveralls.io/repos/github/profusion/sgqlc/badge.svg?branch=master\n :target: https://coveralls.io/github/profusion/sgqlc?branch=master\n\nIntroduction\n------------\n\nThis package offers easy to use `GraphQL `_\nclient. It's composed by the following modules:\n\n- :literal:`sgqlc.types`: declare GraphQL in Python, base to generate and\n interpret queries. Submodule :literal:`sgqlc.types.datetime` will\n provide bindings for :literal:`datetime` and ISO 8601, while\n :literal:`sgqlc.types.relay` will expose ``Node``, ``PageInfo`` and\n ``Connection``.\n\n- :literal:`sgqlc.operation`: use declared types to generate and\n interpret queries.\n\n- :literal:`sgqlc.endpoint`: provide access to GraphQL endpoints, notably\n :literal:`sgqlc.endpoint.http` provides :literal:`HTTPEndpoint` using\n :literal:`urllib.request.urlopen()`.\n\n\nWhat's GraphQL?\n===============\n\nStraight from http://graphql.org:\n\n **A query language for your API**\n\n GraphQL is a query language for APIs and a runtime for fulfilling\n those queries with your existing data. GraphQL provides a complete\n and understandable description of the data in your API, gives\n clients the power to ask for exactly what they need and nothing\n more, makes it easier to evolve APIs over time, and enables\n powerful developer tools.\n\nIt was created by Facebook based on their problems and solutions using\n`REST `_\nto develop applications to consume their APIs. It was publicly\nannounced at\n`React.js Conf 2015 `_\nand started to gain traction since then. Right now there are big names\ntransitioning from REST to GraphQL:\n`Yelp `_\n`Shopify `_\nand `GitHub `_, that did an\nexcellent\n`post `_\nto explain why they did change.\n\nA short list of advantages over REST:\n\n- Built-in schema, with documentation, strong typing and\n introspection. There is no need to use\n `Swagger `_ or any other external tools to play\n with it. Actually GraphQL provides a standard in-browser IDE for\n exploring GraphQL endpoints: https://github.com/graphql/graphiql;\n\n- Only fields you want. The queries must explicitly select which\n fields are required, and that's all you're getting. If more fields\n are added to the type, they **won't break** the API, since the new\n fields won't be returned to old clients, as they didn't ask for such\n fields. This makes much easier to keep APIs stable and **avoids\n versioning**. Standard REST usually delivers all available fields in\n the results, and when new fields are to be included, a new API\n version is added (reflected in the URL path);\n\n- All data in one request. Instead of navigating hypermedia-driven\n RESTful services, like discovering new ``\"_links\": {\"href\"...`` and\n executing a new HTTP request, with GraphQL you specify nested\n queries and let the whole navigation to be done by the server. This\n reduces latency **a lot**;\n\n- Resulting JSON object matches exactly the given query selections, if\n you requested for ``{ parent { child { info } } }``, you're going to\n receive the JSON object ``{\"parent\": {\"child\": {\"info\": value }}}``.\n\nFrom GitHub's\n`Migrating from REST to GraphQL `_\none can see these in real life::\n\n $ curl -v https://api.github.com/orgs/github/members\n [\n {\n \"login\": \"...\",\n \"id\": 1234,\n \"avatar_url\": \"https://avatars3.githubusercontent.com/u/...\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/...\",\n \"html_url\": \"https://github.com/...\",\n \"followers_url\": \"https://api.github.com/users/.../followers\",\n \"following_url\": \"https://api.github.com/users/.../following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/.../gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/.../starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/.../subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/.../orgs\",\n \"repos_url\": \"https://api.github.com/users/.../repos\",\n \"events_url\": \"https://api.github.com/users/.../events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/.../received_events\",\n \"type\": \"User\",\n \"site_admin\": true\n },\n ...\n ]\n\nbrings the whole set of member information, however you just want name\nand avatar URL::\n\n query {\n organization(login:\"github\") { # select the organization\n members(first: 100) { # then select the organization's members\n edges { # edges + node: convention for paginated queries\n node {\n name\n avatarUrl\n }\n }\n }\n }\n }\n\nLikewise, instead of 4 HTTP requests::\n\n curl -v https://api.github.com/repos/profusion/sgqlc/pulls/9\n curl -v https://api.github.com/repos/profusion/sgqlc/pulls/9/commits\n curl -v https://api.github.com/repos/profusion/sgqlc/issues/9/comments\n curl -v https://api.github.com/repos/profusion/sgqlc/pulls/9/reviews\n\nA single GraphQL query brings all the needed information, and just the\nneeded information::\n\n query {\n repository(owner: \"profusion\", name: \"sgqlc\") {\n pullRequest(number: 9) {\n commits(first: 10) { # commits of profusion/sgqlc PR #9\n edges {\n node { commit { oid, message } }\n }\n }\n comments(first: 10) { # comments of profusion/sgqlc PR #9\n edges {\n node {\n body\n author { login }\n }\n }\n }\n reviews(first: 10) { # reviews of profusion/sgqlc/ PR #9\n edges { node { state } }\n }\n }\n }\n }\n\n\nMotivation to create `sgqlc`\n============================\n\nAs seen above, writing GraphQL queries is very easy and equally easy\nto interpret the results, **what was the rationale to create sgqlc?**\n\n- GraphQL has its domain-specific language (DSL), and mixing two\n languages is always painful, as seen with SQL + Python, HTML +\n Python... Being able to write just Python in Python is much\n better. Not to say that GraphQL naming convention is closer to\n Java/JavaScript, using ``aNameFormat`` instead of Python's\n ``a_name_format``.\n\n- Navigating dict-of-stuff is bit painful:\n ``d[\"repository\"][\"pullRequest\"][\"commits\"][\"edges\"][\"node\"]``,\n since these are valid Python identifiers, we better write:\n ``repository.pull_request.commits.edges.node``.\n\n- Handling new ``scalar``. GraphQL allows one to define new scalar\n types, such as ``Date``, ``Time`` and ``DateTime``. Often these are\n serialized as ISO 8601 strings and the user must parse them in their\n application. We offer ``sgqlc.types.datetime`` to automatically\n generate :literal:`datetime.date`, :literal:`datetime.time` and\n :literal:`datetime.datetime`.\n\n- Make it easy to write dynamic queries, including nested. As seen,\n GraphQL can be used to fetch lots of information in one go, however\n if what you need (arguments and fields) changes based on some\n variable, such as user input or cached data, then you need to\n concatenate strings to compose the final query. This can be error\n prone and servers may block you due invalid queries. Some tools\n \"solve\" this by parsing the query locally before sending to\n server. However usually the indentation is screwed and reviewing it\n is painful. We change that approach: use\n :literal:`sgqlc.operation.Operation` and it will always generate valid\n queries, which can be printed out and properly indented. Bonus point\n is that it can be used to later interpret the JSON results into native\n Python objects.\n\n- Usability improvements whenever needed. For instance\n `Relay `_ published their\n `Cursor Connections Specification `_\n and its widely used. To load more data, you need to extend the\n previous data with newly fetched information, updating not only the\n nodes and edges, but also page information. This is done\n automatically by :literal:`sgqlc.types.relay.Connection`.\n\nFuture plans include to generate the Python classes from GraphQL\nschema, which can be automatically fetched from an endpoint using\nthe introspection query.\n\nInstallation\n------------\n\nAutomatic::\n\n pip install sgqlc\n\nFrom source using ``pip``::\n\n pip install .\n\n\nUsage\n-----\n\nTo reach a GraphQL endpoint using synchronous `HTTPEndpoint` with a\nhand-written query (see more at ``examples/basic/http-endpoint.py``):\n\n.. code-block:: python\n\n from sgqlc.endpoint.http import HTTPEndpoint\n\n url = 'http://server.com/graphql'\n headers = {'Authorization': 'bearer TOKEN'}\n\n query = 'query { ... }'\n variables = {'varName': 'value'}\n\n endpoint = HTTPEndpoint(url, headers)\n data = endpoint(query, variables)\n\n\nHowever, writing GraphQL queries and later interpreting the results\nmay be cumbersome, that's solved with our ``sgqlc.types``, that is\nusually paired with ``sgqlc.operation`` to generate queries and then\ninterpret results (see more at ``examples/basic/types.py``). The\nexample below matches a subset of `GitHub API v4\n`_, in GraphQL syntax it would\nbe::\n\n query {\n repository(owner: \"profusion\", name: \"sgqlc\") {\n issues(first: 100) {\n nodes {\n number\n title\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n\nThe output JSON object is:\n\n.. code-block:: json\n\n {\n \"data\": {\n \"repository\": {\n \"issues\": {\n \"nodes\": [\n {\"number\": 1, \"title\": \"...\"},\n {\"number\": 2, \"title\": \"...\"}\n ]\n },\n \"pageInfo\": {\n \"hasNextPage\": false,\n \"endCursor\": \"...\"\n }\n }\n }\n }\n\n.. code-block:: python\n\n from sgqlc.endpoint.http import HTTPEndpoint\n from sgqlc.types import Type, Field, list_of\n from sgqlc.types.relay import Connection, connection_args\n from sgqlc.operation import Operation\n\n # Declare types matching GitHub GraphQL schema:\n class Issue(Type):\n number = int\n title = str\n\n class IssueConnection(Connection): # Connection provides page_info!\n nodes = list_of(Issue)\n\n class Repository(Type):\n issues = Field(IssueConnection, args=connection_args())\n\n class Query(Type): # GraphQL's root\n repository = Field(Repository, args={'owner': str, 'name': str})\n\n # Generate an operation on Query, selecting fields:\n op = Operation(Query)\n # select a field, here with selection arguments, then another field:\n issues = op.repository(owner=owner, name=name).issues(first=100)\n # select sub-fields explicitly: { nodes { number title } }\n issues.nodes.number()\n issues.nodes.title()\n # here uses __fields__() to select by name (*args)\n issues.page_info.__fields__('has_next_page')\n # here uses __fields__() to select by name (**kwargs)\n issues.page_info.__fields__(end_cursor=True)\n\n # you can print the resulting GraphQL\n print(op)\n\n # Call the endpoint:\n data = endpoint(op)\n\n # Interpret results into native objects\n repo = (op + data).repository\n for issue in repo.issues.nodes:\n print(issue)\n\n\nWhy double-underscore and overloaded arithmetic methods?\n========================================================\n\nSince we don't want to cobbler GraphQL fields, we cannot provide\nnicely named methods. Then we use overloaded methods such as\n``__iadd__``, ``__add__``, ``__bytes__`` (compressed GraphQL\nrepresentation) and ``__str__`` (indented GraphQL representation).\n\nTo select fields by name ``__fields__(*names, **names_and_args)``.\nThis helps with repetitive situations and can be used to \"include all\nfields\", or \"include all except...\":\n\n.. code-block:: python\n\n # just 'a' and 'b'\n type_selection.__fields__('a', 'b')\n type_selection.__fields__(a=True, b=True) # equivalent\n\n # a(arg1: value1), b(arg2: value2):\n type_selection.__fields__(\n a={'arg1': value1},\n b={'arg2': value2})\n\n # selects all possible fields\n type_selection.__fields__()\n\n # all but 'a' and 'b'\n type_selection.__fields__(__exclude__=('a', 'b'))\n type_selection.__fields__(a=False, b=False)\n\n\nCode Generator\n--------------\n\nManually converting an existing GraphQL schema to ``sgqlc.types``\nsubclasses is boring and error prone. To aid such task we offer a code\ngenerator that outputs a Python module straight from JSON of an\nintrospection call:\n\n.. code-block:: console\n\n user@host$ python3 -m sgqlc.introspection \\\n --exclude-deprecated \\\n --exclude-description \\\n -H \"Authorization: bearer ${GH_TOKEN}\" \\\n https://api.github.com/graphql \\\n github_schema.json\n user@host$ sgqlc-codegen github_schema.json github_schema.py\n\nThis generates ``github_schema`` that provides the\n:literal:`sgqlc.types.Schema` instance of the same name\n``github_schema``. Then it's a matter of using that in your Python code, as in the example below from ``examples/github/github-agile-dashboard.py``:\n\n.. code-block:: python\n\n from sgqlc.operation import Operation\n from github_schema import github_schema as schema\n\n op = Operation(schema.Query) # note 'schema.'\n\n # -- code below follows as the original usage example:\n\n # select a field, here with selection arguments, then another field:\n issues = op.repository(owner=owner, name=name).issues(first=100)\n # select sub-fields explicitly: { nodes { number title } }\n issues.nodes.number()\n issues.nodes.title()\n # here uses __fields__() to select by name (*args)\n issues.page_info.__fields__('has_next_page')\n # here uses __fields__() to select by name (**kwargs)\n issues.page_info.__fields__(end_cursor=True)\n\n # you can print the resulting GraphQL\n print(op)\n\n # Call the endpoint:\n data = endpoint(op)\n\n # Interpret results into native objects\n repo = (op + data).repository\n for issue in repo.issues.nodes:\n print(issue)\n\n\nAuthors\n-------\n\n- `Gustavo Sverzut Barbieri `_\n\n\nLicense\n-------\n`sgqlc` is licensed under the `ISC `_.\n\n\nGetting started developing\n--------------------------\n\nYou need to use `pipenv `_.\n\n::\n\n pipenv install --dev\n pipenv shell\n\nInstall the git hooks:\n\n::\n\n ./utils/git/install-git-hooks.sh\n\nRun the tests (one of the below):\n\n::\n\n ./utils/git/pre-commit # flake8 and nose\n\n ./setup.py nosetests # only nose (unit/doc tests)\n flake8 --config setup.cfg . # style checks\n\nKeep 100% coverage, you can look at coverage report at\n``cover/index.html``. To do that, prefer `doctest\n`_ so it serves as\nboth documentation and test. However we use `nose\n`_ to write explicit tests that would be\nhard to express using ``doctest``.\n\nBuild and review the generated Sphinx documentation, validate if your\nchanges look right:\n\n::\n\n ./setup.py build_sphinx\n open doc/build/html/index.html\n\n\nTo integrate changes from another branch, please **rebase** instead of\ncreating merge commits (`read more\n`_).\n\n\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/profusion/sgqlc", "keywords": "graphql client http endpoint", "license": "ISCL", "maintainer": "", "maintainer_email": "", "name": "sgqlc", "package_url": "https://pypi.org/project/sgqlc/", "platform": "any", "project_url": "https://pypi.org/project/sgqlc/", "project_urls": { "Homepage": "http://github.com/profusion/sgqlc" }, "release_url": "https://pypi.org/project/sgqlc/8.1/", "requires_dist": [ "graphql-core", "sphinx ; extra == 'sphinx'", "websocket-client ; extra == 'websocket'" ], "requires_python": ">=3.6", "summary": "Simple GraphQL Client", "version": "8.1" }, "last_serial": 5991168, "releases": { "1": [ { "comment_text": "", "digests": { "md5": "567accbe3f57098277a059ea22c39d99", "sha256": "d30bc54c524e703e60ee82a275a316c1b462c5e004bcfa5b43300150f803ec93" }, "downloads": -1, "filename": "sgqlc-1-py3.6.egg", "has_sig": false, "md5_digest": "567accbe3f57098277a059ea22c39d99", "packagetype": "bdist_egg", "python_version": "3.6", "requires_python": null, "size": 95662, "upload_time": "2018-01-26T21:09:37", "url": "https://files.pythonhosted.org/packages/16/69/fb6fa52a2fe2a162fa26d3bd01055621a33fda08a9d665cec3631e6f0f3f/sgqlc-1-py3.6.egg" }, { "comment_text": "", "digests": { "md5": "63e2b4f45209dc620f260d40981535f9", "sha256": "0b51ba1c748bb577859c6fcd99ea731e9ed25204d9ca4a90550eab7584b5c81c" }, "downloads": -1, "filename": "sgqlc-1-py3-none-any.whl", "has_sig": false, "md5_digest": "63e2b4f45209dc620f260d40981535f9", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 53076, "upload_time": "2018-01-26T21:10:14", "url": "https://files.pythonhosted.org/packages/ae/2f/3e250cc4d97f7547a7081e3f588f6f8f2375c1f02a5025e5c2d5db0d9b55/sgqlc-1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5fd580c0797df7b9c23ecf962412973a", "sha256": "4017c57421a1df6bb4cba40098e5a96330b8938537427c0a529a3093514c5202" }, "downloads": -1, "filename": "sgqlc-1.tar.gz", "has_sig": false, "md5_digest": "5fd580c0797df7b9c23ecf962412973a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50099, "upload_time": "2018-01-26T21:04:50", "url": "https://files.pythonhosted.org/packages/3e/3c/ec1d93401becb13eefacd96fcb7950f99b6b3eb72df2a2ce4e6d9f42433d/sgqlc-1.tar.gz" } ], "3": [ { "comment_text": "", "digests": { "md5": "b176e85f84d73ed68a25d4d00ca30396", "sha256": "ac6659052c2784c69d45e7f27d5f1fdc87e4c9313f62e1947203c503614bc063" }, "downloads": -1, "filename": "sgqlc-3.macosx-10.13-x86_64.tar.gz", "has_sig": true, "md5_digest": "b176e85f84d73ed68a25d4d00ca30396", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 41777, "upload_time": "2018-12-06T16:56:37", "url": "https://files.pythonhosted.org/packages/4a/a6/ce3041033bffd194d5c8026437e33d86fed499daba8289dbd6b78ce9b5ad/sgqlc-3.macosx-10.13-x86_64.tar.gz" }, { "comment_text": "", "digests": { "md5": "794cea101b4fefbb18276d6e23d5341f", "sha256": "d219233354e17366df88e0aa747d8c3a5e2ecbe1e492c77b53eb7a0d620b1880" }, "downloads": -1, "filename": "sgqlc-3-py3.7.egg", "has_sig": true, "md5_digest": "794cea101b4fefbb18276d6e23d5341f", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 47206, "upload_time": "2018-12-06T16:56:35", "url": "https://files.pythonhosted.org/packages/bb/c2/49a7e3af98e0f8e368a7f4ebfe35977cf27971ca39ef53fac0a6e571d14f/sgqlc-3-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "4e327df6e2da4e8869f07248065c3798", "sha256": "4c1de9179312e193fd31d42e55f483e6bee6b17fdf2201f152d26a4eab5c4f36" }, "downloads": -1, "filename": "sgqlc-3-py3-none-any.whl", "has_sig": true, "md5_digest": "4e327df6e2da4e8869f07248065c3798", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 48363, "upload_time": "2018-12-06T16:55:29", "url": "https://files.pythonhosted.org/packages/12/53/bc3d5bf6e96f83939e7b3170a7ebc628a6028ee7cae4f4fd9b66d52e62da/sgqlc-3-py3-none-any.whl" } ], "3.2": [ { "comment_text": "", "digests": { "md5": "9a5f16c52c2fbf30230b29dc9036c511", "sha256": "788af5f760e8c9050b7bac593be78d6c305a79276d02d6940b392885734c10b0" }, "downloads": -1, "filename": "sgqlc-3.2-py3-none-any.whl", "has_sig": false, "md5_digest": "9a5f16c52c2fbf30230b29dc9036c511", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 47487, "upload_time": "2018-12-07T14:11:58", "url": "https://files.pythonhosted.org/packages/b6/66/ca768130c8e27b5babe4ad1344684818c4b031bd201a2788639fc4bef3dd/sgqlc-3.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dc0e60e73c825969a8c976d043bc81cf", "sha256": "674e73ed52b5c811fde2bacea394545da8efcd064ee96ff7c53938a409313b04" }, "downloads": -1, "filename": "sgqlc-3.2.tar.gz", "has_sig": false, "md5_digest": "dc0e60e73c825969a8c976d043bc81cf", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 52055, "upload_time": "2018-12-07T14:12:00", "url": "https://files.pythonhosted.org/packages/d2/ca/3bc5e7e1794efa4efd4b28d49461a89f629e104d4f747a9b42639666eab9/sgqlc-3.2.tar.gz" } ], "4.0": [ { "comment_text": "", "digests": { "md5": "ef495299a62e4e6c533f383ce3b60f92", "sha256": "d6308b7db15688e406bd44b7f39d7da2aa5f68b0789c78e5e631f4bf012ddb86" }, "downloads": -1, "filename": "sgqlc-4.0-py3.7.egg", "has_sig": false, "md5_digest": "ef495299a62e4e6c533f383ce3b60f92", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 47455, "upload_time": "2019-01-19T14:14:55", "url": "https://files.pythonhosted.org/packages/37/89/59e465d17df45ccd54a9bd19c78b4e37781d017976888e382bd392c9e9c8/sgqlc-4.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "bc0c8f0b79fb722c4420b2d1252a2097", "sha256": "fb0e134912f9d0b4a5fd7011d57d25f88b3e80495cbd8d91841a8db34d43fad3" }, "downloads": -1, "filename": "sgqlc-4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "bc0c8f0b79fb722c4420b2d1252a2097", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 48648, "upload_time": "2019-01-19T14:14:38", "url": "https://files.pythonhosted.org/packages/a4/b2/c05e56d487fd07846d741e70b52030dd0db5cf427b3e70eae670183b14d6/sgqlc-4.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4e6c787b95623e916ede13b7ce428b87", "sha256": "ca8f970d9a4b6ac173d3889c8a83a9c5d8d1ad2a2aabd7911d2b1cd51c75ac7d" }, "downloads": -1, "filename": "sgqlc-4.0.tar.gz", "has_sig": false, "md5_digest": "4e6c787b95623e916ede13b7ce428b87", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 52327, "upload_time": "2019-01-19T14:12:37", "url": "https://files.pythonhosted.org/packages/0b/02/27c842b2edcedd7c0ea59c92700cf99535a3432c8d3eaa16e5fde512803a/sgqlc-4.0.tar.gz" } ], "5.0": [ { "comment_text": "", "digests": { "md5": "0480cae86bf7cf9beb78c02e4509c82e", "sha256": "7dddba57025e78080bb29fbac770459dca08e1cc392301443fa0550b6bae079f" }, "downloads": -1, "filename": "sgqlc-5.0-py3.7.egg", "has_sig": false, "md5_digest": "0480cae86bf7cf9beb78c02e4509c82e", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 49230, "upload_time": "2019-01-28T11:51:57", "url": "https://files.pythonhosted.org/packages/8a/ee/4e0e1b46feb0e1ef05e0a798824c19f2ba587acf6825ca7b3ea739e65d64/sgqlc-5.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "e1f1a8c98692180658bd6f329c966e43", "sha256": "e45c6a0a0815e92cd9d1164bb661a290acb6f590a5e5394cc1e049415c248ffa" }, "downloads": -1, "filename": "sgqlc-5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e1f1a8c98692180658bd6f329c966e43", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 50424, "upload_time": "2019-01-28T11:51:54", "url": "https://files.pythonhosted.org/packages/33/60/15d960e90efbaa0f12b1c6803353592535725c0a6114d71f99596ca9baf1/sgqlc-5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d8667f6aeeab47f18c22cff0046e6b47", "sha256": "82a45cef86b9dd9686117d072667c3ead05c87e865b5a88d50b5aefc20df6aea" }, "downloads": -1, "filename": "sgqlc-5.0.tar.gz", "has_sig": false, "md5_digest": "d8667f6aeeab47f18c22cff0046e6b47", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 54113, "upload_time": "2019-01-28T11:51:58", "url": "https://files.pythonhosted.org/packages/9c/31/77581bdf5091a658fc9ad419b82cfb982e1e3d179fb3d808cdb31c8f7b75/sgqlc-5.0.tar.gz" } ], "6.0": [ { "comment_text": "", "digests": { "md5": "0a5b407889bbf88af0d475237eeb5c62", "sha256": "259197599b88af99cd4c92c1d1d792894228bcba0d64e1780d8872f46adb2882" }, "downloads": -1, "filename": "sgqlc-6.0-py3.7.egg", "has_sig": false, "md5_digest": "0a5b407889bbf88af0d475237eeb5c62", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 49258, "upload_time": "2019-02-05T16:55:49", "url": "https://files.pythonhosted.org/packages/1f/26/047998ad52c133683e5bce186f33a63e5493f62281fdcf3452c2b0d79bd4/sgqlc-6.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "7f978c7af8152bce046de287b9e014bc", "sha256": "71efda75651036ec990602b297cb6e1242b7d7be4f2a9125e977dae106c16037" }, "downloads": -1, "filename": "sgqlc-6.0-py3-none-any.whl", "has_sig": false, "md5_digest": "7f978c7af8152bce046de287b9e014bc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 50452, "upload_time": "2019-02-05T16:55:47", "url": "https://files.pythonhosted.org/packages/28/7d/0a3a1440019e87962110663c8828b00a8e98764ae256a3de86f3517877e2/sgqlc-6.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a079efac2f04a171cc6116ba1d2a7892", "sha256": "fa6c1fe110008e38add39c6c20c122d14bd41bc45d91cf79dc6d2ccd0561164b" }, "downloads": -1, "filename": "sgqlc-6.0.tar.gz", "has_sig": false, "md5_digest": "a079efac2f04a171cc6116ba1d2a7892", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 54136, "upload_time": "2019-02-05T16:55:51", "url": "https://files.pythonhosted.org/packages/6c/1f/cacd52e18ec372191818459007093e2430572f276f2f606c7d1ec1d9996c/sgqlc-6.0.tar.gz" } ], "7.0": [ { "comment_text": "", "digests": { "md5": "954a59d2b27f15c2c37c059ba60bad5f", "sha256": "59c079deea585856f5b19aa0d23fb36084acd5e9729b62efdcd3b64c6324a11d" }, "downloads": -1, "filename": "sgqlc-7.0-py3.7.egg", "has_sig": false, "md5_digest": "954a59d2b27f15c2c37c059ba60bad5f", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 50695, "upload_time": "2019-02-24T16:40:24", "url": "https://files.pythonhosted.org/packages/9b/80/b3ed0972e5d5da12a7ff5ed5cd45de9c953306916d8a8840ed326a1d4706/sgqlc-7.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "c932dddb390e165e458e38de02fc636e", "sha256": "1444b05b788da63de2515ab4dc6e491ba4bcff733cae685b29ba8891db2eef6a" }, "downloads": -1, "filename": "sgqlc-7.0-py3-none-any.whl", "has_sig": false, "md5_digest": "c932dddb390e165e458e38de02fc636e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 51884, "upload_time": "2019-02-24T16:40:22", "url": "https://files.pythonhosted.org/packages/d5/22/678eb5f60df37fc8ef30ec1cfeff36a9e640707a3c392574a628a752c9bd/sgqlc-7.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2f9cb410fb163b27ca42186c5527dc2b", "sha256": "cdc0dcfe2c471048cc0eb66cda9657d4e3b263dbc97b90a8d00d71c0e0d0a7ff" }, "downloads": -1, "filename": "sgqlc-7.0.tar.gz", "has_sig": false, "md5_digest": "2f9cb410fb163b27ca42186c5527dc2b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 55478, "upload_time": "2019-02-24T16:40:26", "url": "https://files.pythonhosted.org/packages/49/55/f3ffaf776a7af22b11436eade04ca1a16b25c4aacc9e5d4211a55fd912ca/sgqlc-7.0.tar.gz" } ], "8.0": [ { "comment_text": "", "digests": { "md5": "8ec8c75fe7f94a57ba0712d1a5985ea9", "sha256": "abee0b008996db2f7342f9ff1f4bc13f7058812ba13efbd81b20a765ca48ef0e" }, "downloads": -1, "filename": "sgqlc-8.0-py3.7.egg", "has_sig": false, "md5_digest": "8ec8c75fe7f94a57ba0712d1a5985ea9", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 55179, "upload_time": "2019-09-09T19:24:10", "url": "https://files.pythonhosted.org/packages/64/8f/32ce163fc72b39b1e548f0f4b27c3db040fed45b5dce7da9cef62195bbef/sgqlc-8.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "922a48c4d69c123a095f6df779bac19e", "sha256": "04a39dc2f365a30712ae4a3a210ed7e914ce15ef28267e4094b20bab1b4b15a4" }, "downloads": -1, "filename": "sgqlc-8.0-py3-none-any.whl", "has_sig": false, "md5_digest": "922a48c4d69c123a095f6df779bac19e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 56357, "upload_time": "2019-09-09T19:24:08", "url": "https://files.pythonhosted.org/packages/b9/0c/594f5461a4c7fcb406a4d5586d55ce98ac60bb42cc351ad0ddb44fd0ad64/sgqlc-8.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "309c3c29bce4b155d733fade22409525", "sha256": "57177f75e0c443386b069a483b27c9c3b03ebbfe1cf49aae42ec310e296c93e8" }, "downloads": -1, "filename": "sgqlc-8.0.tar.gz", "has_sig": false, "md5_digest": "309c3c29bce4b155d733fade22409525", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 218648, "upload_time": "2019-09-09T19:24:13", "url": "https://files.pythonhosted.org/packages/0e/03/cb247a42cba3265602689b4340a7a49703049bfb27a25e3471ebc69a77f3/sgqlc-8.0.tar.gz" } ], "8.1": [ { "comment_text": "", "digests": { "md5": "b600243384ea3621d7a85f6694d40fb3", "sha256": "ad83279aafae85fc00026d0ce59c464442dd5ab8b73eab7f6346d8225b8a40fb" }, "downloads": -1, "filename": "sgqlc-8.1-py3.7.egg", "has_sig": false, "md5_digest": "b600243384ea3621d7a85f6694d40fb3", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 55223, "upload_time": "2019-10-17T16:39:36", "url": "https://files.pythonhosted.org/packages/f3/42/06d96edeb318664383247c2f447de65c44d5a757cd110485ce4265fe80d8/sgqlc-8.1-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "975203b9028c0467c7db0f5b8a2e9763", "sha256": "4a154c5decf1703b92458b84eff65a43ed8744e5ab93194ab95710fd19341571" }, "downloads": -1, "filename": "sgqlc-8.1-py3-none-any.whl", "has_sig": false, "md5_digest": "975203b9028c0467c7db0f5b8a2e9763", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 56401, "upload_time": "2019-10-17T16:39:33", "url": "https://files.pythonhosted.org/packages/fb/ab/93eaabc6d378ce9a9e5627b6d98e285a4601f858b439e6fcf020da42f542/sgqlc-8.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ff535758a1cda860fb47dd19b28de3b8", "sha256": "4a4dcc28aa7402f813ecc9d0fbf482cbfecd9a35f8ea3361f1eaf8a21643f8db" }, "downloads": -1, "filename": "sgqlc-8.1.tar.gz", "has_sig": false, "md5_digest": "ff535758a1cda860fb47dd19b28de3b8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 218552, "upload_time": "2019-10-17T16:39:40", "url": "https://files.pythonhosted.org/packages/b8/dc/9aa9cd35036eda7665cad75a4703a638ce6d4b1b3b428b98df079fee3584/sgqlc-8.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b600243384ea3621d7a85f6694d40fb3", "sha256": "ad83279aafae85fc00026d0ce59c464442dd5ab8b73eab7f6346d8225b8a40fb" }, "downloads": -1, "filename": "sgqlc-8.1-py3.7.egg", "has_sig": false, "md5_digest": "b600243384ea3621d7a85f6694d40fb3", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3.6", "size": 55223, "upload_time": "2019-10-17T16:39:36", "url": "https://files.pythonhosted.org/packages/f3/42/06d96edeb318664383247c2f447de65c44d5a757cd110485ce4265fe80d8/sgqlc-8.1-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "975203b9028c0467c7db0f5b8a2e9763", "sha256": "4a154c5decf1703b92458b84eff65a43ed8744e5ab93194ab95710fd19341571" }, "downloads": -1, "filename": "sgqlc-8.1-py3-none-any.whl", "has_sig": false, "md5_digest": "975203b9028c0467c7db0f5b8a2e9763", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 56401, "upload_time": "2019-10-17T16:39:33", "url": "https://files.pythonhosted.org/packages/fb/ab/93eaabc6d378ce9a9e5627b6d98e285a4601f858b439e6fcf020da42f542/sgqlc-8.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ff535758a1cda860fb47dd19b28de3b8", "sha256": "4a4dcc28aa7402f813ecc9d0fbf482cbfecd9a35f8ea3361f1eaf8a21643f8db" }, "downloads": -1, "filename": "sgqlc-8.1.tar.gz", "has_sig": false, "md5_digest": "ff535758a1cda860fb47dd19b28de3b8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 218552, "upload_time": "2019-10-17T16:39:40", "url": "https://files.pythonhosted.org/packages/b8/dc/9aa9cd35036eda7665cad75a4703a638ce6d4b1b3b428b98df079fee3584/sgqlc-8.1.tar.gz" } ] }