Skip to main content

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"

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.0.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.0-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pydantic_views-0.3.0.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.0.tar.gz
Algorithm Hash digest
SHA256 b9827f8e73d9f80f4639c65cefac3b8f4f8618478f8aeb8bf78fd1b7098543df
MD5 91e19e75f0a1b62f75d684662342c519
BLAKE2b-256 bd6d43ba85857e88dd27168d84777c4e5a0077c3c7fc144b48dee90bc65e3f81

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pydantic_views-0.3.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc486339ec78e0b7b0898d7d90af731c8cb9a19c57dfdac9e4bf62f147e59a2f
MD5 ce6e8c5fb7a00460eb7c2893008c6679
BLAKE2b-256 72887ed552f2634155668dbd90f15b0821caab9162a5bd6580b3435485805fe7

See more details on using hashes here.

Release history Release notifications | RSS feed

Supported by

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