Views for Pydantic models
Project description
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9827f8e73d9f80f4639c65cefac3b8f4f8618478f8aeb8bf78fd1b7098543df
|
|
| MD5 |
91e19e75f0a1b62f75d684662342c519
|
|
| BLAKE2b-256 |
bd6d43ba85857e88dd27168d84777c4e5a0077c3c7fc144b48dee90bc65e3f81
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc486339ec78e0b7b0898d7d90af731c8cb9a19c57dfdac9e4bf62f147e59a2f
|
|
| MD5 |
ce6e8c5fb7a00460eb7c2893008c6679
|
|
| BLAKE2b-256 |
72887ed552f2634155668dbd90f15b0821caab9162a5bd6580b3435485805fe7
|