pydantic-strict-partial


Namepydantic-strict-partial JSON
Version 0.6.2 PyPI version JSON
download
home_pagehttps://github.com/ADR-007/pydantic-strict-partial
SummaryMakes partial Pydantic models without making fields nullable.
upload_time2025-01-22 13:16:49
maintainerNone
docs_urlNone
authorAdrian Dankiv
requires_python<4.0,>=3.10
licenseMIT
keywords pydantic partial fastapi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pydantic-strict-partial

[![PyPI version](https://badge.fury.io/py/pydantic-strict-partial.svg)](https://badge.fury.io/py/pydantic-strict-partial)
[![PyPI Supported Python Versions](https://img.shields.io/pypi/pyversions/pydantic-strict-partial.svg)](https://pypi.python.org/pypi/pydantic-strict-partial/)
[![CI](https://github.com/ADR-007/pydantic-strict-partial/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/ADR-007/pydantic-strict-partial/actions/workflows/ci.yaml)
![badge](https://raw.githubusercontent.com/ADR-007/pydantic-strict-partial/_xml_coverage_reports/data/main/./badge.svg)

## About

Create partial models based on the original Pydantic models. 

This makes all the fields optional. 
This **doesn't** make them nullable and **doesn't** disable validation.
The only thing it does is provide default values for those fields (`None` by default), 
so you can use `model.model_dump(exclude_unset=True)` command to receive specified values only.

The most common use case is a `PATCH` request on **FastAPI** endpoints where you want to allow partial updates.

## Installation

`pydantic-strict-partial` compatible with Python 3.10+ and Pydantic 2.1+.

### Using pip
```bash
pip install pydantic-strict-partial
```

### Using poetry
```bash
poetry add pydantic-strict-partial
```

## Usage

```python
from typing import Annotated

from annotated_types import Ge
from pydantic import BaseModel

from pydantic_strict_partial import create_partial_model


class UserSchema(BaseModel):
    name: str
    nickname: str | None
    age: Annotated[int, Ge(18)]


UserPartialUpdateSchema = create_partial_model(UserSchema)

assert UserPartialUpdateSchema(age=20).model_dump(exclude_unset=True) == {
    'age': 20
}

UserPartialUpdateSchema(name=None)  # raises ValidationError
UserPartialUpdateSchema(age=17)  # raises ValidationError

```

There is also possible to specify a limited list of fields to be partial:

```python
UserPartialUpdateSchema = create_partial_model(UserSchema, 'name', 'nickname')
```

Or to make all fields partial except for the specified ones:

```python
UserPartialCreateSchema = create_partial_model(UserSchema, required_fields=['age'])
```

## Known limitations

#### MyPy: "is not valid as a type" error

You may be faced with `Variable "UserPartialUpdateSchema" is not valid as a type` error.
There is no good solution for that. But the next approach can be used as a workaround: 

```py
class UserPartialUpdateSchema(create_partial_model(UserSchema)):  # type: ignore[misc]
    pass
```

## Alternatives

[pydantic-partial](https://github.com/team23/pydantic-partial) - it makes all fields nullable and disables all validators, which is not suitable for payload validation on `PATCH` endpoints.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ADR-007/pydantic-strict-partial",
    "name": "pydantic-strict-partial",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": "pydantic, partial, fastapi",
    "author": "Adrian Dankiv",
    "author_email": "adr-007@ukr.net",
    "download_url": "https://files.pythonhosted.org/packages/bd/a6/7d5a0116e7d517f57242b0dd90272ce154713c4a5772d069059eccbf715f/pydantic_strict_partial-0.6.2.tar.gz",
    "platform": null,
    "description": "# pydantic-strict-partial\n\n[![PyPI version](https://badge.fury.io/py/pydantic-strict-partial.svg)](https://badge.fury.io/py/pydantic-strict-partial)\n[![PyPI Supported Python Versions](https://img.shields.io/pypi/pyversions/pydantic-strict-partial.svg)](https://pypi.python.org/pypi/pydantic-strict-partial/)\n[![CI](https://github.com/ADR-007/pydantic-strict-partial/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/ADR-007/pydantic-strict-partial/actions/workflows/ci.yaml)\n![badge](https://raw.githubusercontent.com/ADR-007/pydantic-strict-partial/_xml_coverage_reports/data/main/./badge.svg)\n\n## About\n\nCreate partial models based on the original Pydantic models. \n\nThis makes all the fields optional. \nThis **doesn't** make them nullable and **doesn't** disable validation.\nThe only thing it does is provide default values for those fields (`None` by default), \nso you can use `model.model_dump(exclude_unset=True)` command to receive specified values only.\n\nThe most common use case is a `PATCH` request on **FastAPI** endpoints where you want to allow partial updates.\n\n## Installation\n\n`pydantic-strict-partial` compatible with Python 3.10+ and Pydantic 2.1+.\n\n### Using pip\n```bash\npip install pydantic-strict-partial\n```\n\n### Using poetry\n```bash\npoetry add pydantic-strict-partial\n```\n\n## Usage\n\n```python\nfrom typing import Annotated\n\nfrom annotated_types import Ge\nfrom pydantic import BaseModel\n\nfrom pydantic_strict_partial import create_partial_model\n\n\nclass UserSchema(BaseModel):\n    name: str\n    nickname: str | None\n    age: Annotated[int, Ge(18)]\n\n\nUserPartialUpdateSchema = create_partial_model(UserSchema)\n\nassert UserPartialUpdateSchema(age=20).model_dump(exclude_unset=True) == {\n    'age': 20\n}\n\nUserPartialUpdateSchema(name=None)  # raises ValidationError\nUserPartialUpdateSchema(age=17)  # raises ValidationError\n\n```\n\nThere is also possible to specify a limited list of fields to be partial:\n\n```python\nUserPartialUpdateSchema = create_partial_model(UserSchema, 'name', 'nickname')\n```\n\nOr to make all fields partial except for the specified ones:\n\n```python\nUserPartialCreateSchema = create_partial_model(UserSchema, required_fields=['age'])\n```\n\n## Known limitations\n\n#### MyPy: \"is not valid as a type\" error\n\nYou may be faced with `Variable \"UserPartialUpdateSchema\" is not valid as a type` error.\nThere is no good solution for that. But the next approach can be used as a workaround: \n\n```py\nclass UserPartialUpdateSchema(create_partial_model(UserSchema)):  # type: ignore[misc]\n    pass\n```\n\n## Alternatives\n\n[pydantic-partial](https://github.com/team23/pydantic-partial) - it makes all fields nullable and disables all validators, which is not suitable for payload validation on `PATCH` endpoints.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Makes partial Pydantic models without making fields nullable.",
    "version": "0.6.2",
    "project_urls": {
        "Homepage": "https://github.com/ADR-007/pydantic-strict-partial"
    },
    "split_keywords": [
        "pydantic",
        " partial",
        " fastapi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e5a75b40a0f327193c4cfebbc2b26df7b1b02304fca40da23825ca231a11efe9",
                "md5": "8f90764310e744afd564f3a0fa49f562",
                "sha256": "acb1f020eec6d892dc104184a0cc3d471622d7025216e2eb9f4b9e5ce78acebc"
            },
            "downloads": -1,
            "filename": "pydantic_strict_partial-0.6.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8f90764310e744afd564f3a0fa49f562",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 4108,
            "upload_time": "2025-01-22T13:16:48",
            "upload_time_iso_8601": "2025-01-22T13:16:48.465557Z",
            "url": "https://files.pythonhosted.org/packages/e5/a7/5b40a0f327193c4cfebbc2b26df7b1b02304fca40da23825ca231a11efe9/pydantic_strict_partial-0.6.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bda67d5a0116e7d517f57242b0dd90272ce154713c4a5772d069059eccbf715f",
                "md5": "6c9ac0a0fe0b8c357ccabcb54f0811a1",
                "sha256": "d5827fccfa30c63f8a7c7303079f245bbb7af7eed6eb53a0854264072007083c"
            },
            "downloads": -1,
            "filename": "pydantic_strict_partial-0.6.2.tar.gz",
            "has_sig": false,
            "md5_digest": "6c9ac0a0fe0b8c357ccabcb54f0811a1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 4822,
            "upload_time": "2025-01-22T13:16:49",
            "upload_time_iso_8601": "2025-01-22T13:16:49.982563Z",
            "url": "https://files.pythonhosted.org/packages/bd/a6/7d5a0116e7d517f57242b0dd90272ce154713c4a5772d069059eccbf715f/pydantic_strict_partial-0.6.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-22 13:16:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ADR-007",
    "github_project": "pydantic-strict-partial",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pydantic-strict-partial"
}
        
Elapsed time: 0.47239s