pydantic / pydantic-settings

Settings management using pydantic
https://docs.pydantic.dev/latest/usage/pydantic_settings/
MIT License
508 stars 50 forks source link

Typing JsonValue field #270

Closed skhaz closed 3 months ago

skhaz commented 3 months ago

I am using Pydantic and Pydantic Settings, and they have been working very well. However, I have a JSON field in my .env, and using the JSON field it loads correctly (see functional example below). However, I would like to type this JSON field that Pydantic loads. I do not want it to be generic; I want it to have two fields (username and password) in its object. Typing is precisely why I use Pydantic.

Is there any way to do this?

from typing import Deque, List, Optional, Tuple
from pydantic import BaseModel, Field
from pydantic import RedisDsn
from pydantic import JsonValue
from pydantic_settings import BaseSettings
from pydantic_settings import SettingsConfigDict
from typing import Optional

class Account(BaseModel):
    username: str
    password: str

class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

    accounts: JsonValue = Field(default=..., json_schema_extra=Account.model_json_schema())

settings = Settings()

print(settings.accounts) # I would like it to be possible here to press `.` and have suggestions for username or password come up.

.env

ACCOUNTS={"username": "rodrigo@stackoverflow.com", "password": "abc123"}
hramezani commented 3 months ago

Why don't you use the Account model as sub type:

accounts: Account = Field(default=..., json_schema_extra=Account.model_json_schema())

Then you have access to settings.accounts.username

skhaz commented 3 months ago

I did not know. This is very nice! Thank you!