Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

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.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.

Release history Release notifications | RSS feed

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