{"id":19684785,"url":"https://github.com/lonelyteapot/pygraphic","last_synced_at":"2025-07-31T22:40:55.559Z","repository":{"id":44543900,"uuid":"511579060","full_name":"lonelyteapot/pygraphic","owner":"lonelyteapot","description":"Client-side GraphQL query generator based on pydantic","archived":false,"fork":false,"pushed_at":"2022-07-24T19:12:15.000Z","size":122,"stargazers_count":1,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-14T17:44:22.096Z","etag":null,"topics":["graphql-clients","graphql-codegen","graphql-query-generator","pydantic"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pygraphic/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lonelyteapot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-07T15:22:16.000Z","updated_at":"2024-11-29T18:12:35.000Z","dependencies_parsed_at":"2022-09-06T20:50:35.387Z","dependency_job_id":null,"html_url":"https://github.com/lonelyteapot/pygraphic","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/lonelyteapot/pygraphic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonelyteapot%2Fpygraphic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonelyteapot%2Fpygraphic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonelyteapot%2Fpygraphic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonelyteapot%2Fpygraphic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lonelyteapot","download_url":"https://codeload.github.com/lonelyteapot/pygraphic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonelyteapot%2Fpygraphic/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265482298,"owners_count":23774028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql-clients","graphql-codegen","graphql-query-generator","pydantic"],"created_at":"2024-11-11T18:19:00.018Z","updated_at":"2025-07-16T04:43:31.134Z","avatar_url":"https://github.com/lonelyteapot.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pygraphic\n\u003cp\u003e\n\u003ca href=\"https://pypi.org/project/pygraphic\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/status/pygraphic\" alt=\"Status\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/pygraphic\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/pygraphic\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/lonelyteapot/pygraphic/actions/workflows/test.yml?query=branch%3Amain\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/workflow/status/lonelyteapot/pygraphic/Unit%20tests/main?label=tests\" alt=\"Tests\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/lonelyteapot/pygraphic\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/codecov/c/github/lonelyteapot/pygraphic\" alt=\"Coverage\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\nClient-side GraphQL query generator based on [pydantic].\n\n## Why?\n\nWorking with GraphQL in Python seems simple... If you're fine with dictionaries, lack of\nautocompletion and unexpected errors.\n\nSome tools allow you to generate Python code from GraphQL schemas. One of them, [turms],\neven generates pydantic models from GQL documents. This approach can be problematic:\nqueries are written in GraphQL, not Python, so the codebase you're actually working with\nis out of your control; and the main advantage of pydantic — data validation — is\nmissing!\n\n## Workflow\n\nPygraphic is the opposite of [turms]:\n\n1. For each individual query, you define pydantic models that you want to request,\n   optionally with validators and other configuration;\n\n2. Pygraphic converts those definitions to raw GraphQL documents *(basically strings)*;\n\n3. Using a GraphQL or an HTTP client, you make requests with those documents and get\n   back JSON responses;\n\n4. Pydantic converts those responses to instances of the defined models and validates\n   them;\n\n5. You use the validated data, while enjoying autocompletion and type safety!\n\n## Roadmap\n\nPygraphic is in development stage. Some major features are missing or might work\nincorrectly. The API may change at any time.\n\nSee [ROADMAP.md][Roadmap] for the list of implemented/missing features.\n\n## Examples\n\nExamples are kept in the\n[/examples](https://github.com/lonelyteapot/pygraphic/tree/main/examples) folder.  \nQueries that they're expected to produce are stored in the\n[/golden_files](https://github.com/lonelyteapot/pygraphic/tree/main/folden_files)\nfolder.\n\nMost examples are based on [GitHub's GraphQL API](https://docs.github.com/en/graphql).\nIf you want to run them, you need to \n[generate a personal access token](https://github.com/settings/tokens) and assign it to\nthe environment variable called `GITHUB_TOKEN` (with VSCode, the best way to do this is\nto create a [`.env` file](https://www.dotenv.org/env) in the project's root directory).\n\nHere's the gist:\n\n### main.py\n\n``` python\nimport os\nimport requests\nfrom pygraphic import GQLQuery, GQLType\n\n# Define data models\nclass License(GQLType):\n    id: str\n    name: str\n    description: str\n\n# Define query model\nclass GetAllLicenses(GQLQuery):\n    licenses: list[License]\n\n# Generate the GraphQL query string\nquery_str = GetAllLicenses.get_query_string()\n\n# Make the request\nTOKEN = os.environ[\"GITHUB_TOKEN\"]\nresponse = requests.post(\n    url=\"https://api.github.com/graphql\",\n    json={\n        \"query\": query_str,\n    },\n    headers={\n        \"Authorization\": f\"bearer {TOKEN}\",\n    },\n)\n\n# Parse the response\nresponse_data = response.json().get('data')\nif response_data is None:\n    print('Query failed')\nresult = GetAllLicenses.parse_obj(response_data)\n\n# Print the results\nfor license in result.licenses:\n    print(license.name)\n```\n\n### Generated query string\n\n``` gql\nquery GetAllLicenses {\n  licenses {\n    id\n    name\n    description\n  }\n}\n```\n\n## Contribution\n\nThis project is developed on [GitHub].\n\nIf you have any general questions or need help — you're welcome in the [Discussions]\nsection.\n\nIf you encounter any bugs or missing features — file new [Issues], but make sure to\ncheck the existing ones first.\n\nIf you want to solve an issue, go ahead and create a [Pull Request][Pulls]! It will be\nreviewed and hopefully merged. Help is always appreciated.\n\n## License\n\nCopyright \u0026copy; 2022, Dmitry Semenov. Released under the [MIT license][License].\n\n\n[GitHub]: https://github.com/lonelyteapot/pygraphic\n[Discussions]: https://github.com/lonelyteapot/pygraphic/discussions\n[Issues]: https://github.com/lonelyteapot/pygraphic/issues\n[Pulls]: https://github.com/lonelyteapot/pygraphic/pulls\n[License]: https://github.com/lonelyteapot/pygraphic/blob/main/LICENSE\n[Roadmap]: https://github.com/lonelyteapot/pygraphic/blob/main/ROADMAP.md\n\n[pydantic]: https://pypi.org/project/pydantic/\n[turms]: https://pypi.org/project/turms/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flonelyteapot%2Fpygraphic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flonelyteapot%2Fpygraphic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flonelyteapot%2Fpygraphic/lists"}