{"id":20280357,"url":"https://github.com/yezz123/pyngo","last_synced_at":"2025-04-10T03:56:10.404Z","repository":{"id":40416632,"uuid":"431663546","full_name":"yezz123/pyngo","owner":"yezz123","description":"Pydantic model support for Django \u0026 Django-Rest-Framework ✨","archived":false,"fork":false,"pushed_at":"2025-04-07T21:27:02.000Z","size":257,"stargazers_count":87,"open_issues_count":2,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-10T03:56:04.645Z","etag":null,"topics":["django","django-rest-framework","fastapi","openapi","pydantic","python","python3","typed"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pyngo/","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/yezz123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["yezz123"]}},"created_at":"2021-11-25T00:14:05.000Z","updated_at":"2025-03-10T12:21:26.000Z","dependencies_parsed_at":"2023-02-18T00:45:59.496Z","dependency_job_id":"c0b3fd8b-cf93-485a-906c-5e939a7187e5","html_url":"https://github.com/yezz123/pyngo","commit_stats":{"total_commits":59,"total_committers":4,"mean_commits":14.75,"dds":"0.23728813559322037","last_synced_commit":"bf67f6681e5166f57452b2d50122dcb7ac8d7e9f"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fpyngo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fpyngo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fpyngo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fpyngo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yezz123","download_url":"https://codeload.github.com/yezz123/pyngo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248155001,"owners_count":21056542,"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":["django","django-rest-framework","fastapi","openapi","pydantic","python","python3","typed"],"created_at":"2024-11-14T13:35:25.206Z","updated_at":"2025-04-10T03:56:10.386Z","avatar_url":"https://github.com/yezz123.png","language":"Python","funding_links":["https://github.com/sponsors/yezz123"],"categories":[],"sub_categories":[],"readme":"# Pyngo :snake:\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003eUtils to help integrate pydantic into Django projects\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/yezz123/pyngo/actions/workflows/ci.yml\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://github.com/yezz123/pyngo/actions/workflows/ci.yml/badge.svg\" alt=\"Test\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/yezz123/pyngo\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/yezz123/pyngo/branch/main/graph/badge.svg\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/pyngo\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/pyngo?color=%2334D058\u0026label=pypi%20package\" alt=\"Package version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/pyngo\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/pyversions/pyngo.svg?color=%2334D058\" alt=\"Supported Python versions\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pepy.tech/project/pyngo\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://static.pepy.tech/badge/pyngo\" alt=\"Test\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Installation\n\nYou can add pyngo in a few easy steps. First of all, install the dependency:\n\n```sh\n$ pip install pyngo\n\n---\u003e 100%\n\nSuccessfully installed pyngo\n```\n\n---\n\n## Features 🎉\n\n- Using Pydantic to Build your Models in Django Project.\n- Using `OpenAPI` utilities to build params from a basic model.\n- using `QueryDictModel` to build `Pydantic` models from a `QueryDict` object.\n- propagate any errors from Pydantic in Django Rest Framework.\n- Tested in Python 3.10 and up.\n\n## Examples 📚\n\n### OpenAPI\n\n- `pyngo.openapi_params()` can build params from a basic model\n\n```py\nfrom pydantic import BaseModel\nfrom pyngo import openapi_params\n\nclass Model(BaseModel):\n   bingo: int\n\nprint(openapi_params(Model))\n```\n\n- `pyngo.ParameterDict.required` is set according to the type of the variable\n\n```py\nfrom typing import Optional\nfrom pydantic import BaseModel\nfrom pyngo import openapi_params\n\nclass Model(BaseModel):\n   required_param: int\n   optional_param: Optional[int]\n\nprint(openapi_params(Model))\n```\n\nOther fields can be set through the field’s info:\n\n```py\nfrom pydantic import BaseModel, Field\nfrom pyngo import openapi_params\n\nclass WithDescription(BaseModel):\n   described_param: str = Field(\n      description=\"Hello World Use Me!\"\n   )\n\nclass InPath(BaseModel):\n   path_param: str = Field(location=\"path\")\n\nclass WithDeprecated(BaseModel):\n   deprecated_field: bool = Field(deprecated=True)\n\nclass WithNoAllowEmpty(BaseModel):\n   can_be_empty: bool = Field(allowEmptyValue=False)\n\nprint(openapi_params(WithDescription)[0][\"description\"])\nprint(openapi_params(InPath)[0][\"in\"])\nprint(openapi_params(WithDeprecated)[0][\"deprecated\"])\nprint(openapi_params(WithNoAllowEmpty)[0][\"allowEmptyValue\"])\n```\n\n### Django\n\n- `pyngo.querydict_to_dict()` and `pyngo.QueryDictModel` are conveniences for building a `pydantic.BaseModel` from a `django.QueryDict`.\n\n```py\nfrom typing import List\nfrom django.http import QueryDict\nfrom pydantic import BaseModel\nfrom pyngo import QueryDictModel, querydict_to_dict\n\nclass Model(BaseModel):\n   single_param: int\n   list_param: List[str]\n\nclass QueryModel(QueryDictModel):\n   single_param: int\n   list_param: List[str]\n\nquery_dict = QueryDict(\"single_param=20\u0026list_param=Life\")\n\nprint(Model.model_validate(querydict_to_dict(query_dict, Model)))\nprint(QueryModel.model_validate(query_dict))\n```\n\n\u003e **Note:** Don't forget to Setup the Django Project.\n\n### Django Rest Framework\n\n- `pyngo.drf_error_details()` will propagate any errors from Pydantic.\n\n```py\nfrom pydantic import BaseModel, ValidationError\nfrom pyngo import drf_error_details\n\nclass Model(BaseModel):\n   foo: int\n   bar: str\n\ndata = {\"foo\": \"Cat\"}\n\ntry:\n   Model.model_validate(data)\nexcept ValidationError as e:\n   print(drf_error_details(e))\n```\n\nErrors descend into nested fields:\n\n```py\nfrom typing import List\nfrom pydantic import BaseModel, ValidationError\nfrom pyngo import drf_error_details\n\nclass Framework(BaseModel):\n   frm_id: int\n\nclass Language(BaseModel):\n   framework: List[Framework]\n\ndata = {\"framework\": [{\"frm_id\": \"not_a_number\"}, {}]}\nexpected_details = {\n   \"framework\": {\n      \"0\": {\"frm_id\": [\"value is not a valid integer\"]},\n      \"1\": {\"frm_id\": [\"field required\"]},\n   }\n}\n\ntry:\n   Language.model_validate(data)\nexcept ValidationError as e:\n   print(drf_error_details(e))\n```\n\n## Development 🚧\n\n### Setup environment 📦\n\nYou should create a virtual environment and activate it:\n\n```bash\npython -m venv venv/\n```\n\n```bash\nsource venv/bin/activate\n```\n\nAnd then install the development dependencies:\n\n```bash\n# Install dependencies\npip install -e .[test,lint]\n```\n\n### Run tests 🌝\n\nYou can run all the tests with:\n\n```bash\nbash scripts/test.sh\n```\n\n\u003e Note: You can also generate a coverage report with:\n\n```bash\nbash scripts/test_html.sh\n```\n\n### Format the code 🍂\n\nExecute the following command to apply `pre-commit` formatting:\n\n```bash\nbash scripts/format.sh\n```\n\nExecute the following command to apply `mypy` type checking:\n\n```bash\nbash scripts/lint.sh\n```\n\n## License 🍻\n\nThis project is licensed under the terms of the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Fpyngo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyezz123%2Fpyngo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Fpyngo/lists"}