Skip to main content

pydantic-computed

A new decorator for pydantic allowing you to define dynamic fields that are computed from other properties.

Installation

Install the package by running

pip install pydantic_computed

Examples and use cases

A computed integer property

from pydantic import BaseModel
from pydantic_computed import Computed, computed

class ComputedModelInt(BaseModel):
    a: int
    b: int
    c: Computed[int]
    @computed('c')
    def calculate_c(a: int, b: int, **kwargs):
        return a + b

model = ComputedModelInt(a=1, b=2)
print(model.c) # Outputs 3

Multiple computed properties

from pydantic import BaseModel
from pydantic_computed import Computed, computed

class MultipleComputed(BaseModel):
    a: int
    b: int
    c: Computed[int]
    d: Computed[int]
    e: Computed[int]
    @computed('c')
    def calc_c(a: int, b: int, **kwargs):
        return a + b

    @computed('d')
    def calc_d(c: int, **kwargs): # Note that property d uses the value of the computed property c (The order of declaration matters!)
        return c * 2

model = MultipleComputed(a=1, b=2)
print(model.c) # Outputs 3
print(model.d) # Outputs 6

Since all properties are passed as **kwargs to calculate_c, we can use the property names for the parameters

Complex types

Suppose you set up a FastAPI application where you have users and orders stored in a database. All Models in the database have an automatically generated id. Now you want to be able to dynamically generate links to those objects. E.g. the user with id=3 is accessible on the endpoint http://my-api/users/3 Instead of storing those links in the database you can simply generate them with the computed decorator. example:

from pydantic import BaseModel, Field
from pydantic_computed import Computed, computed

class Link(BaseModel):
    href: str
    method: str

class SchemaLinked(BaseModel):
    id: int
    base_url: str
    link: Computed[Link]
    @computed('link')
    def compute_link( id: int, base_url: str, **kwargs):        
        return Link(href=f'{base_url}/{id}', method='GET')

class User(SchemaLinked):
    base_url: str = Field('/users', exclude=True)
    username: str

class Order(SchemaLinked):
    base_url: str = Field('/orders', exclude=True)
    user: User

user = User(id=3, username='exampleuser') 
user.json()
"""
{
    id: 3,
    username: "exampleuser",
    link: {
        href: "/users/3",
        method: "GET"
    }
}
"""
order = Order(id=2, user=user)
order.json()
"""
{
    id: 2,
    link: {
        href: "/orders/2",
        method: "GET"
    },
    user: {
        id: 3,
        username: "exampleuser",
        link: {
            href: "/users/3",
            method: "GET"
        }
    }
}
"""

Vector example:

from pydantic import BaseModel
from pydantic_computed import computed, Computed
import math

class Point(BaseModel):
    x: int
    y: int

class Vector(BaseModel):
    p1: Point
    p2: Point
    x: Computed[float]
    y: Computed[float]
    weight: Computed[float]

    @computed('x')
    def compute_x(p1: Point, p2: Point, **kwargs):
        return p2.x - p1.x
    @computed('y')
    def compute_y(p1: Point, p2: Point, **kwargs):
        return p2.y - p1.y
    @computed('weight')
    def compute_weight(x: float, y: float, **kwargs):
        return math.sqrt(x ** 2 + y ** 2)

v1 = Vector(p1=Point(x=0,y=0), p2=Point(x=1,y=0))
print(v1.weight) # Outputs 1.0
v1.p2 = Point(x=2,y=0)
print(v1.weight) # Outputs now 2.0 since p2 changed
# NOTE: if we would have written v1.p2.x = 2 instead of v1.p2 = Point(x=2, y=0), it would not have worked, because of the way pydantic triggers validations
# The computed field only gets updated if one of the fields in the same model changes (in this case it is property p1 of Vector)

Metadata

Release files for pydantic-computed 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydantic-computed 0.2.2
File Size Uploaded
pydantic_computed-0.2.2.tar.gz 4.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydantic-computed 0.2.2
File Interpreter ABI Platform
pydantic_computed-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 9.5 kB

Release files / pydantic_computed-0.2.2.tar.gz

Download URL pydantic_computed-0.2.2.tar.gz
Size 4.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b48b00952137ea2fe1919ccb08c7e0795d9658f1ff77d289d140e86157d5fca1
BLAKE2b-256 checksum
How to use checksums
ae006d7028511c59864b869b0f31e75f261317b48b51a3db0c8e3316cc6495c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.3.1 CPython/3.10.6 Windows/10

Release files / pydantic_computed-0.2.2-py3-none-any.whl

Download URL pydantic_computed-0.2.2-py3-none-any.whl
Size 4.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4f6982a8f3a5220e558af6c7971ac00e5e2c75e9d41da0d145d316f08e9882e1
BLAKE2b-256 checksum
How to use checksums
71d5f3fccd9314f5aa165a88b3f19b01974bae67706e57a6aef30d3f2862b394
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.3.1 CPython/3.10.6 Windows/10

Release history Release notifications | RSS feed

This release

0.2.2 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page