Skip to content

Commit a8ad18c

Browse files
use Pydantic 'SettingsConfigDict' instead of custom func to set attributes via env vars
1 parent d39ef0e commit a8ad18c

File tree

1 file changed

+57
-17
lines changed

1 file changed

+57
-17
lines changed

src/anyvlm/schemas/vlm.py

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""Schemas relating to VLM API."""
22

3-
import os
43
from typing import ClassVar, Literal, Self
54

65
from pydantic import BaseModel, ConfigDict, Field, model_validator
6+
from pydantic_settings import BaseSettings, SettingsConfigDict
77

88
from anyvlm.utils.types import Zygosity
99

@@ -12,41 +12,67 @@
1212
RESULT_ENTITY_TYPE = "genomicVariant"
1313

1414

15-
class MissingEnvironmentVariableError(Exception):
16-
"""Raised when a required environment variable is not set."""
15+
class HandoverSettings(BaseSettings):
16+
"""Settings for 'HandoverType' class"""
1717

18+
id: str
19+
label: str
1820

19-
def _get_environment_var(key: str) -> str:
20-
value: str | None = os.environ.get(key)
21-
if not value:
22-
message = f"Missing required environment variable: {key}"
23-
raise MissingEnvironmentVariableError(message)
24-
return value
21+
model_config = SettingsConfigDict(
22+
env_prefix="HANDOVER_TYPE_",
23+
extra="ignore",
24+
)
25+
26+
27+
handover_type_settings = HandoverSettings() # type: ignore
2528

2629

2730
class HandoverType(BaseModel):
2831
"""The type of handover the parent `BeaconHandover` represents."""
2932

3033
id: str = Field(
31-
default_factory=lambda: _get_environment_var("HANDOVER_TYPE_ID"),
34+
"",
3235
description="Node-specific identifier",
36+
frozen=True,
3337
)
3438
label: str = Field(
35-
default_factory=lambda: _get_environment_var("HANDOVER_TYPE_LABEL"),
39+
"",
3640
description="Node-specific label",
41+
frozen=True,
42+
)
43+
44+
model_config = ConfigDict(
45+
extra="forbid",
3746
)
3847

39-
# custom __init__ to prevent overriding attributes that are set via environment variables
48+
# custom __init__ to prevent overriding attributes that are static/set via environment variables
4049
def __init__(self) -> None:
41-
super().__init__()
50+
super().__init__(
51+
id=handover_type_settings.id,
52+
label=handover_type_settings.label,
53+
)
54+
55+
56+
class BeaconHandoverSettings(BaseSettings):
57+
"""Settings for 'BeaconHandover' class"""
58+
59+
url: str
60+
61+
model_config = SettingsConfigDict(
62+
env_prefix="BEACON_HANDOVER_",
63+
extra="ignore",
64+
)
65+
66+
67+
beacon_handover_settings = BeaconHandoverSettings() # type: ignore
4268

4369

4470
class BeaconHandover(BaseModel):
4571
"""Describes how users can get more information about the results provided in the parent `VlmResponse`"""
4672

4773
handoverType: HandoverType = Field(default=HandoverType())
4874
url: str = Field(
49-
default_factory=lambda: _get_environment_var("BEACON_HANDOVER_URL"),
75+
"",
5076
description="""
5177
A url which directs users to more detailed information about the results tabulated by the API. Must be human-readable.
5278
Ideally links directly to the variant specified in the query, but can be a generic search page if necessary.
@@ -55,7 +81,7 @@ class BeaconHandover(BaseModel):
5581

5682
# custom __init__ to prevent overriding attributes that are static/set via environment variables
5783
def __init__(self) -> None:
58-
super().__init__()
84+
super().__init__(url=beacon_handover_settings.url)
5985

6086

6187
class ReturnedSchema(BaseModel):
@@ -75,6 +101,20 @@ class ReturnedSchema(BaseModel):
75101
model_config = ConfigDict(populate_by_name=True)
76102

77103

104+
class MetaSettings(BaseSettings):
105+
"""Settings for 'Meta' class"""
106+
107+
beaconId: str = Field(..., alias="BEACON_NODE_ID")
108+
109+
model_config = SettingsConfigDict(
110+
env_prefix="",
111+
extra="ignore",
112+
)
113+
114+
115+
meta_settings = MetaSettings() # type: ignore
116+
117+
78118
class Meta(BaseModel):
79119
"""Relevant metadata about the results provided in the parent `VlmResponse`"""
80120

@@ -83,7 +123,7 @@ class Meta(BaseModel):
83123
description="The version of the VLM API that this response conforms to",
84124
)
85125
beaconId: str = Field(
86-
default_factory=lambda: _get_environment_var("BEACON_NODE_ID"),
126+
default="",
87127
description="""
88128
The Id of a Beacon. Usually a reversed domain string, but any URI is acceptable. The purpose of this attribute is,
89129
in the context of a Beacon network, to disambiguate responses coming from different Beacons. See the beacon documentation
@@ -94,7 +134,7 @@ class Meta(BaseModel):
94134

95135
# custom __init__ to prevent overriding attributes that are static or set via environment variables
96136
def __init__(self) -> None:
97-
super().__init__()
137+
super().__init__(beaconId=meta_settings.beaconId)
98138

99139

100140
class ResponseSummary(BaseModel):

0 commit comments

Comments
 (0)