Skip to main content

Views for Pydantic models

Project description

Documentation Status PyPI - Python Version PyPI - Types PyPI - License PyPI - Version

Typed views for Pydantic models

pydantic-views lets you derive focused, type-safe Pydantic models (“views”) from a base model. Each view exposes only the fields appropriate for a given operation—create, update, load, or a custom flow—so you avoid hand-maintaining parallel schemas.

Typical service signatures become easy to express:

ExampleModelCreate = BuilderCreate().build_view(ExampleModel)
ExampleModelCreateResult = BuilderCreateResult().build_view(ExampleModel)
ExampleModelLoad = BuilderLoad().build_view(ExampleModel)
ExampleModelUpdate = BuilderUpdate().build_view(ExampleModel)

def create(input: ExampleModelCreate) -> ExampleModelCreateResult: ...
def load(model_id: str) -> ExampleModelLoad: ...
def update(model_id: str, input: ExampleModelUpdate) -> ExampleModelLoad: ...

Features

  • Unlimited views per model (create, update, load, custom).

  • Works on nested models; referenced models get views too.

  • Builders for common patterns, or define views manually.

  • Fully typed with shipped py.typed and tests.

  • Open source and published on PyPI.

Installation

Using pip:

pip install pydantic-views

Using poetry:

poetry add pydantic-views

Using uv:

uv add pydantic-views

Quickstart

Mark each field with its access mode using the provided annotations. Unmarked fields default to read/write.

from typing import Annotated

from pydantic import BaseModel, computed_field, gt
from pydantic_views import AccessMode, Hidden, ReadOnly, ReadOnlyOnCreation

class ExampleModel(BaseModel):
    # Unmarked fields are read/write everywhere.
    field_str: str

    # Read-only fields are removed from create and update views.
    field_read_only_str: ReadOnly[str]

    # Read-only-on-creation fields are hidden on create, update and load views,
    # but appear on create-result views.
    field_api_secret: ReadOnlyOnCreation[str]

    # Combine access modes with Annotated and keep validators (gt in this case).
    field_int: Annotated[int, AccessMode.READ_ONLY, AccessMode.WRITE_ONLY_ON_CREATION, gt(5)]

    # Hidden fields never appear.
    field_hidden_int: Hidden[int]

    # Computed fields appear only on read views.
    @computed_field
    def field_computed_field(self) -> int:
        return self.field_hidden_int * 5

Build a load view:

from pydantic_views import BuilderLoad

ExampleModelLoad = BuilderLoad().build_view(ExampleModel)

Which is equivalent to:

from pydantic import gt
from pydantic_views import View

class ExampleModelLoad(View[ExampleModel]):
    field_str: str
    field_int: Annotated[int, gt(5)]
    field_computed_field: int

To build an update view:

from pydantic_views import BuilderUpdate

ExampleModelUpdate = BuilderUpdate().build_view(ExampleModel)

Which is equivalent to:

from pydantic import Field, PydanticUndefined
from pydantic_views import View

class ExampleModelUpdate(View[ExampleModel]):
    field_str: str = Field(default_factory=lambda: PydanticUndefined)

On Update views every field uses a default factory that returns PydanticUndefined, so fields become optional. Applying the view to a model only updates values that were set.

original_model = ExampleModel(
    field_str="anything"
    field_read_only_str="anything"
    field_api_secret="anything"
    field_int=10
    field_hidden_int=33
)

update = ExampleModelUpdate(field_str="new_data")

updated_model = update.view_apply_to(original_model)

assert isinstance(updated_model, ExampleModel)
assert updated_model.field_str == "new_data"

If a field is not set on the update view, the original value is kept.

original_model = ExampleModel(
    field_str="anything"
    field_read_only_str="anything"
    field_api_secret="anything"
    field_int=10
    field_hidden_int=33
)

update = ExampleModelUpdate()

updated_model = update.view_apply_to(original_model)

assert isinstance(updated_model, ExampleModel)
assert updated_model.field_str == "anything"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydantic_views-0.3.0b3.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydantic_views-0.3.0b3-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_views-0.3.0b3.tar.gz.

File metadata

  • Download URL: pydantic_views-0.3.0b3.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pydantic_views-0.3.0b3.tar.gz
Algorithm Hash digest
SHA256 764aa777391e67fa1c48da89dc7ac5ee5733cab5b880ac5ff5a2d7c500fbcff6
MD5 65bc9b391d830719e723ade23d5ef38d
BLAKE2b-256 66103bcb14cd9d2fda23fd8dbd408a818c30b4cc8b2f62c6b3ffca537e90cfd3

See more details on using hashes here.

File details

Details for the file pydantic_views-0.3.0b3-py3-none-any.whl.

File metadata

  • Download URL: pydantic_views-0.3.0b3-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pydantic_views-0.3.0b3-py3-none-any.whl
Algorithm Hash digest
SHA256 67741666d6efdfff2b67ec93673c7dd8bd8a52951e173c0f90e6de335ef1e8ab
MD5 fa08c0f2c1fe378bda7e631e1f6f228c
BLAKE2b-256 4cfed769718f6b521f0f42d81b129a06416c32843d33f57123aebc6f1804a28e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page