Skip to content

settings

PixelApiSettings

Bases: BaseSettings

Settings for the Pixel API client

Source code in src/pixel_client/settings.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
class PixelApiSettings(BaseSettings):
    """
    Settings for the Pixel API client
    """

    @classmethod
    def from_env_file(cls, env_file: Path | str) -> "PixelApiSettings":
        """Instantiate the settings from an environment file.

        Warning:
            Environment variables will always take precedence over the values in the file.
        """
        return cls(_env_file=env_file)  # type: ignore

    model_config = SettingsConfigDict(frozen=True, extra="ignore")  # Makes it hashable

    PIXEL_ENV: Literal["dev", "test", "prod"] = Field(
        validation_alias=pixel_env_choices, default="prod"
    )

    PIXEL_USERNAME: str | None = Field(
        validation_alias=pixel_username_choices, default=None
    )
    """The username for the Keycloak server. Required unless `PIXEL_API_KEY` is set."""

    PIXEL_PASSWORD: SecretStr | None = Field(
        validation_alias=pixel_password_choices, default=None
    )
    """The password for the Keycloak server. Required unless `PIXEL_API_KEY` is set."""

    PIXEL_API_KEY: SecretStr | None = None
    """A Pixel api key, used instead of `PIXEL_USERNAME` / `PIXEL_PASSWORD`.

    Mint one with [`create_api_key`][pixel_client.PixelClient.create_api_key]. The
    token is only ever shown once, at creation time.
    """

    PIXEL_TENANT: str = Field(validation_alias=pixel_realm_choices)
    """The realm for the Keycloak server"""

    PIXEL_AUTH_SERVER_URL_OVERRIDE: str | None = Field(
        alias="PIXEL_AUTH_SERVER_URL", default=None
    )
    PIXEL_API_URL_OVERRIDE: str | None = Field(alias="PIXEL_API_URL", default=None)

    @model_validator(mode="after")
    def validate_credentials(self) -> "PixelApiSettings":
        """Require exactly one set of credentials: an api key, or a username and password."""
        has_api_key = self.PIXEL_API_KEY is not None
        has_username = self.PIXEL_USERNAME is not None
        has_password = self.PIXEL_PASSWORD is not None
        if has_api_key and (has_username or has_password):
            raise ValueError(
                "Both PIXEL_API_KEY and PIXEL_USERNAME/PIXEL_PASSWORD are set. "
                "Provide exactly one set of credentials."
            )
        if not has_api_key and has_username != has_password:
            missing = "PIXEL_PASSWORD" if has_username else "PIXEL_USERNAME"
            raise ValueError(
                f"{missing} is missing. Username/password authentication needs both "
                "PIXEL_USERNAME and PIXEL_PASSWORD."
            )
        if not has_api_key and not has_username:
            raise ValueError(
                "No credentials provided. Set either PIXEL_API_KEY, or both "
                "PIXEL_USERNAME and PIXEL_PASSWORD."
            )
        return self

    @property
    def PIXEL_CLIENT_ID(self):
        return "frontend"

    @property
    def PIXEL_REALM(self):
        return self.PIXEL_TENANT.capitalize()

    @property
    def PIXEL_API_URL(self):
        return (
            self.PIXEL_API_URL_OVERRIDE
            or f"https://{self.PIXEL_ENV}.api.geodatapixel.no/{self.PIXEL_REALM.lower()}"
        )

    @property
    def PIXEL_AUTH_SERVER_URL(self):
        return (
            self.PIXEL_AUTH_SERVER_URL_OVERRIDE
            or f"https://{self.PIXEL_ENV}.keycloak.geodatapixel.no"
        )

    PIXEL_CLIENT_NO_VERSION_CHECK: bool = False
    """If True, the client will not check for a newer version of the pixel-client package on startup."""

PIXEL_ENV class-attribute instance-attribute

PIXEL_ENV: Literal["dev", "test", "prod"] = Field(
    validation_alias=pixel_env_choices, default="prod"
)

PIXEL_USERNAME class-attribute instance-attribute

PIXEL_USERNAME: str | None = Field(
    validation_alias=pixel_username_choices, default=None
)

The username for the Keycloak server. Required unless PIXEL_API_KEY is set.

PIXEL_PASSWORD class-attribute instance-attribute

PIXEL_PASSWORD: SecretStr | None = Field(
    validation_alias=pixel_password_choices, default=None
)

The password for the Keycloak server. Required unless PIXEL_API_KEY is set.

PIXEL_API_KEY class-attribute instance-attribute

PIXEL_API_KEY: SecretStr | None = None

A Pixel api key, used instead of PIXEL_USERNAME / PIXEL_PASSWORD.

Mint one with create_api_key. The token is only ever shown once, at creation time.

PIXEL_TENANT class-attribute instance-attribute

PIXEL_TENANT: str = Field(
    validation_alias=pixel_realm_choices
)

The realm for the Keycloak server

PIXEL_AUTH_SERVER_URL_OVERRIDE class-attribute instance-attribute

PIXEL_AUTH_SERVER_URL_OVERRIDE: str | None = Field(
    alias="PIXEL_AUTH_SERVER_URL", default=None
)

PIXEL_API_URL_OVERRIDE class-attribute instance-attribute

PIXEL_API_URL_OVERRIDE: str | None = Field(
    alias="PIXEL_API_URL", default=None
)

PIXEL_CLIENT_ID property

PIXEL_CLIENT_ID

PIXEL_REALM property

PIXEL_REALM

PIXEL_API_URL property

PIXEL_API_URL

PIXEL_AUTH_SERVER_URL property

PIXEL_AUTH_SERVER_URL

PIXEL_CLIENT_NO_VERSION_CHECK class-attribute instance-attribute

PIXEL_CLIENT_NO_VERSION_CHECK: bool = False

If True, the client will not check for a newer version of the pixel-client package on startup.

from_env_file classmethod

from_env_file(env_file: Path | str) -> PixelApiSettings

Instantiate the settings from an environment file.

Warning

Environment variables will always take precedence over the values in the file.

Source code in src/pixel_client/settings.py
19
20
21
22
23
24
25
26
@classmethod
def from_env_file(cls, env_file: Path | str) -> "PixelApiSettings":
    """Instantiate the settings from an environment file.

    Warning:
        Environment variables will always take precedence over the values in the file.
    """
    return cls(_env_file=env_file)  # type: ignore

validate_credentials

validate_credentials() -> PixelApiSettings

Require exactly one set of credentials: an api key, or a username and password.

Source code in src/pixel_client/settings.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@model_validator(mode="after")
def validate_credentials(self) -> "PixelApiSettings":
    """Require exactly one set of credentials: an api key, or a username and password."""
    has_api_key = self.PIXEL_API_KEY is not None
    has_username = self.PIXEL_USERNAME is not None
    has_password = self.PIXEL_PASSWORD is not None
    if has_api_key and (has_username or has_password):
        raise ValueError(
            "Both PIXEL_API_KEY and PIXEL_USERNAME/PIXEL_PASSWORD are set. "
            "Provide exactly one set of credentials."
        )
    if not has_api_key and has_username != has_password:
        missing = "PIXEL_PASSWORD" if has_username else "PIXEL_USERNAME"
        raise ValueError(
            f"{missing} is missing. Username/password authentication needs both "
            "PIXEL_USERNAME and PIXEL_PASSWORD."
        )
    if not has_api_key and not has_username:
        raise ValueError(
            "No credentials provided. Set either PIXEL_API_KEY, or both "
            "PIXEL_USERNAME and PIXEL_PASSWORD."
        )
    return self