from pydantic import BaseModelclass Grafana(BaseModel):user: strpassword: strhost: strport: strapi_key: str | None = NoneGRAFANA_URL = f"http://{user}:{password}@{host}:{port}"API_DATASOURCES = "/api/datasources"API_KEYS = "/api/auth/keys"
With Pydantic I get two unbound variables error messages for user
, password
, etc. in GRAFANA_URL
.
Is there a way to solve this? In a regular class, I would just create GRAFANA_URL
in the __init__
method. With Pydantic, I'm not sure how to proceed.
Option A: Use a @validator
See the validators documentation for details.
from typing import Anyfrom pydantic import BaseModel, validatorclass Model(BaseModel):foo: strbar: strfoobar: str = ""@validator("foobar", always=True)def set_if_empty(cls, v: str, values: dict[str, Any]) -> str:if v == "":return values["foo"] + values["bar"]return vobj = Model(foo="a", bar="b")
print(obj) # foo='a' bar='b' foobar='ab'
That way foobar
remains a regular model field.
Note that for this to work, foobar
must be defined after foo
and bar
. Otherwise you will have to use a root validator.
Option B: Make it a @property
from pydantic import BaseModelclass Model(BaseModel):foo: strbar: str@propertydef foobar(self) -> str:return self.foo + self.barobj = Model(foo="a", bar="b")
print(obj) # foo='a' bar='b'
print(obj.foobar) # ab
Then foobar
will not be a model field anymore and therefore not part of the schema. That may or may not be relevant to you.
Option C: Make it a @computed_field
(Pydantic v2 only!)
Defining computed fields will be available for Pydantic 2.
from pydantic import BaseModel, computed_fieldclass Model(BaseModel):foo: strbar: str@computed_field@propertydef foobar(self) -> str:return self.foo + self.barobj = Model(foo="a", bar="b")
print(obj) # foo='a' bar='b' foobar='ab'