{"id":21459958,"url":"https://github.com/allmonday/pydantic2-resolve","last_synced_at":"2025-07-15T02:31:52.743Z","repository":{"id":206509493,"uuid":"712704681","full_name":"allmonday/pydantic2-resolve","owner":"allmonday","description":"A hierarchical, schema-based solution for fetching and crafting data, from simple to complicated.","archived":true,"fork":false,"pushed_at":"2024-10-28T23:56:55.000Z","size":1223,"stargazers_count":38,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T17:38:42.441Z","etag":null,"topics":["composition-oriented","fastapi","graphql","pydantic"],"latest_commit_sha":null,"homepage":"https://allmonday.github.io/pydantic-resolve/","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/allmonday.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-01T02:37:26.000Z","updated_at":"2025-02-10T15:48:46.000Z","dependencies_parsed_at":"2023-12-16T15:44:04.411Z","dependency_job_id":"0d2ba1b6-37a6-45f5-bc78-9a0b1bd36b18","html_url":"https://github.com/allmonday/pydantic2-resolve","commit_stats":null,"previous_names":["allmonday/pydantic2-resolve"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/allmonday/pydantic2-resolve","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Fpydantic2-resolve","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Fpydantic2-resolve/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Fpydantic2-resolve/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Fpydantic2-resolve/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allmonday","download_url":"https://codeload.github.com/allmonday/pydantic2-resolve/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Fpydantic2-resolve/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265390887,"owners_count":23757605,"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":["composition-oriented","fastapi","graphql","pydantic"],"created_at":"2024-11-23T06:37:20.957Z","updated_at":"2025-07-15T02:31:52.137Z","avatar_url":"https://github.com/allmonday.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"[![pypi](https://img.shields.io/pypi/v/pydantic2-resolve.svg)](https://pypi.python.org/pypi/pydantic2-resolve)\n[![Downloads](https://static.pepy.tech/personalized-badge/pydantic2-resolve?period=month\u0026units=abbreviation\u0026left_color=grey\u0026right_color=orange\u0026left_text=Downloads)](https://pepy.tech/project/pydantic2-resolve)\n![Python Versions](https://img.shields.io/pypi/pyversions/pydantic2-resolve)\n[![CI](https://github.com/allmonday/pydantic2-resolve/actions/workflows/ci.yml/badge.svg)](https://github.com/allmonday/pydantic2-resolve/actions/workflows/ci.yml)\n![Test Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/allmonday/372580ad111c92340dac39987c0c4e9a/raw/covbadge.json)\n\n**This repo has been merged into pydantic-resolve and no more maintained**\n\n**This repo has been merged into pydantic-resolve and no more maintained**\n\n**This repo has been merged into pydantic-resolve and no more maintained**\n\n\u003chr\u003e\n\n\nPydantic-resolve is a schema based, hierarchical solution for fetching and crafting data.\n\nIt combines the advantages of restful and graphql.\n\n\n![img](doc/intro.jpeg)\n\n\nAdvantages:\n1. use declaretive way to define view data, easy to maintain and develop\n2. enhance the traditional restful response, to support gql-like style data structure.\n3. provide post_method and other tools to craft resolved data.\n\n\n[Discord](https://discord.com/channels/1197929379951558797/1197929379951558800)\n\n\n## Install\n\n\u003e If you are using pydantic v1, please use [pydantic-resolve](https://github.com/allmonday/pydantic-resolve) instead.\n\n\n```shell\npip install pydantic2-resolve\n```\n\n## Concepts from GraphQL to Pydantic-resolve\n\n```gql\nquery {\n    MyBlogSite {\n        name\n        blogs {\n            id\n            title\n            comments {\n                id\n                content\n            }\n            # comment_count\n        }\n        # comment_count\n    }\n}\n```\n\nThis is how we do queries in GraphQL, dive by describing schema and field names.\n\nAssuming `comment_count` is a extra field (length of comment), which is required and calculated by client after fetching the data.\n\nclient side so need to iterate over the blogs to get the length and the sum, which is boring (things gets worse if the structure is deeper).\n\nIn pydantic-resolve, we can handle comment_count at server side, by transforming the query into pydantic schemas and attach some resolve, post methods.\n\n\n```python\nimport blog_service as bs\nimport comment_service as cs\n\nclass MySite(BaseModel):\n    blogs: list[MySiteBlog] = []\n    async def resolve_blogs(self):\n        return await bs.get_blogs()\n\n    comment_count: int = 0\n    def post_comment_count(self):\n        return sum([b.comment_count for b in self.blogs])\n\n# -------- inherit and extend ----------\nclass MySiteBlog(bs.Blog):  \n    comments: list[cs.Comment] = []\n    def resolve_comments(self, loader=LoaderDepend(cs.blog_to_comments_loader)):\n        return loader.load(self.id)\n\n    comment_count: int = 0\n    def post_comment_count(self):\n        return len(self.comments)\n        \nasync def main():\n    my_blog_site = MyBlogSite(name: \"tangkikodo's blog\")\n    my_blog_site = await Resolver().resolve(my_blog_site)\n```\n\nschemas , query functions and loader functions are provided by entity's service modules. \n\nSo that we can declare customrized schema by simpily **INHERIT** and **EXTEND** from base schemas.\n\n\u003e This just sounds like columns of values (inherit) and of foreign keys (extend) in concept of relational database.\n\nAfter transforming GraphQL query into pydantic schemas, post calculation become dead easy, and no more iterations.\n\n\u003e Collector is a powerful feature for adjusting data structures. https://allmonday.github.io/pydantic-resolve/reference_api/#collector\n\n## API Reference\nhttps://allmonday.github.io/pydantic-resolve/reference_api/\n\n## Composition oriented development-pattern (wip)\nhttps://github.com/allmonday/composition-oriented-development-pattern\n\n\n## Unittest\n\n```shell\npoetry run python -m unittest  # or\npoetry run pytest  # or\npoetry run tox\n```\n\n## Coverage\n\n```shell\npoetry run coverage run -m pytest\npoetry run coverage report -m\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallmonday%2Fpydantic2-resolve","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallmonday%2Fpydantic2-resolve","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallmonday%2Fpydantic2-resolve/lists"}