Skip to content

Commit 0adb119

Browse files
committed
feat (Configuration): add attribute docstrings and enable use_attribute_docstrings for the pydantic models
feat (Configuration): documenting other attributes fix: formatting and remove caching
1 parent 47c2b29 commit 0adb119

File tree

1 file changed

+119
-4
lines changed

1 file changed

+119
-4
lines changed

diracx-core/src/diracx/core/config/schema.py

Lines changed: 119 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727

2828

2929
class BaseModel(_BaseModel):
30-
model_config = ConfigDict(extra="forbid", frozen=True)
30+
model_config = ConfigDict(
31+
extra="forbid", frozen=True, use_attribute_docstrings=True
32+
)
3133

3234
@model_validator(mode="before")
3335
@classmethod
@@ -68,28 +70,51 @@ def legacy_adaptor(cls, v):
6870

6971
class UserConfig(BaseModel):
7072
PreferedUsername: str
73+
"""Preferred username for the user account."""
7174
DNs: list[str] = []
75+
"""Distinguished Names of the user's certificates (Mandatory for certificate-based authentication)."""
7276
Email: EmailStr | None = None
77+
"""User e-mail address (Mandatory for user registration)."""
7378
Suspended: list[str] = []
79+
"""List of VOs where the user is suspended."""
7480
Quota: int | None = None
81+
"""Quota assigned to the user, expressed in MBs."""
7582

7683

7784
class GroupConfig(BaseModel):
7885
AutoAddVOMS: bool = False
86+
"""Controls automatic addition of VOMS extension when creating proxies."""
7987
AutoUploadPilotProxy: bool = False
88+
"""Controls automatic Proxy upload for Pilot groups."""
8089
AutoUploadProxy: bool = False
90+
"""Controls automatic Proxy upload for users in this group."""
8191
JobShare: int = 1000
92+
"""Share of computing resources allocated to this group for fair share scheduling."""
8293
Properties: SerializableSet[SecurityProperty]
94+
"""Group properties (set permissions of the group users).
95+
96+
Examples: NormalUser, GenericPilot, ServiceAdministrator.
97+
"""
8398
Quota: int | None = None
99+
"""Group-specific quota override."""
84100
Users: SerializableSet[str]
101+
"""DIRAC user logins that belong to this group."""
85102
AllowBackgroundTQs: bool = False
103+
"""Allow background Task Queues for this group."""
86104
VOMSRole: str | None = None
105+
"""Role of the users in the VO (e.g., '/lhcb' for LHCb VO)."""
87106
AutoSyncVOMS: bool = False
107+
"""Automatically synchronize group membership with VOMS server."""
88108

89109

90110
class IdpConfig(BaseModel):
91111
URL: str
112+
"""The authorization server's issuer identifier.
113+
114+
This is a URL that uses the 'https' scheme and has no query or fragment components.
115+
"""
92116
ClientID: str
117+
"""OAuth 2.0 client identifier received after client registration with the identity provider."""
93118

94119
@property
95120
def server_metadata_url(self):
@@ -98,25 +123,44 @@ def server_metadata_url(self):
98123

99124
class SupportInfo(BaseModel):
100125
Email: str | None = None
126+
"""Support contact email address."""
101127
Webpage: str | None = None
128+
"""Support webpage URL."""
102129
Message: str = "Please contact system administrator"
130+
"""Default support message displayed to users."""
103131

104132

105133
class RegistryConfig(BaseModel):
106134
IdP: IdpConfig
135+
"""Registered identity provider associated with this VO."""
107136
Support: SupportInfo = Field(default_factory=SupportInfo)
137+
"""Support contact information for this VO."""
108138
DefaultGroup: str
139+
"""Default user group to be used for new users in this VO."""
109140
DefaultStorageQuota: float = 0
141+
"""Default storage quota in GB for users in this VO."""
110142
DefaultProxyLifeTime: int = 12 * 60 * 60
143+
"""Default proxy time expressed in seconds (default: 43200 = 12 hours)."""
111144
VOMSName: str | None = None
145+
"""Real VOMS VO name, if this VO is associated with VOMS VO."""
112146

113147
Users: MutableMapping[str, UserConfig]
148+
"""DIRAC users section, subsections represent the name of the user."""
114149
Groups: MutableMapping[str, GroupConfig]
150+
"""DIRAC groups section, subsections represent the name of the group."""
115151

116152
def sub_from_preferred_username(self, preferred_username: str) -> str:
117153
"""Get the user sub from the preferred username.
118154
119-
TODO: This could easily be cached or optimised
155+
Args:
156+
preferred_username: The preferred username to look up.
157+
158+
Returns:
159+
The user sub (subject identifier) for the given username.
160+
161+
Raises:
162+
KeyError: If no user with the given preferred username is found.
163+
120164
"""
121165
for sub, user in self.Users.items():
122166
if user.PreferedUsername == preferred_username:
@@ -126,80 +170,135 @@ def sub_from_preferred_username(self, preferred_username: str) -> str:
126170

127171
class DIRACConfig(BaseModel):
128172
NoSetup: bool = False
173+
"""Flag to skip setup procedures during DIRAC initialization. Takes a boolean value. By default false."""
129174

130175

131176
class JobMonitoringConfig(BaseModel):
132177
GlobalJobsInfo: bool = True
178+
"""Enable global job information monitoring across all VOs."""
133179

134180

135181
class JobSchedulingConfig(BaseModel):
136182
EnableSharesCorrection: bool = False
183+
"""Enable correction of job shares based on historical usage."""
137184
MaxRescheduling: int = 3
185+
"""Maximum number of times a job can be rescheduled."""
138186

139187

140188
class ServicesConfig(BaseModel):
141189
Catalogs: MutableMapping[str, Any] | None = None
190+
"""Configuration for data catalog services."""
142191
JobMonitoring: JobMonitoringConfig = JobMonitoringConfig()
192+
"""Job monitoring service configuration."""
143193
JobScheduling: JobSchedulingConfig = JobSchedulingConfig()
194+
"""Job scheduling service configuration."""
144195

145196

146197
class JobDescriptionConfig(BaseModel):
147198
DefaultCPUTime: int = 86400
199+
"""Default CPU time limit for jobs in seconds (default: 24 hours)."""
148200
DefaultPriority: int = 1
201+
"""Default job priority."""
149202
MinCPUTime: int = 100
203+
"""Minimum allowed CPU time for jobs in seconds."""
150204
MinPriority: int = 0
205+
"""Minimum allowed job priority."""
151206
MaxCPUTime: int = 500000
207+
"""Maximum allowed CPU time for jobs in seconds."""
152208
MaxPriority: int = 10
209+
"""Maximum allowed job priority."""
153210
MaxInputData: int = 100
211+
"""Maximum number of input data files per job."""
154212
AllowedJobTypes: list[str] = ["User", "Test", "Hospital"]
213+
"""List of allowed job types."""
155214

156215

157216
class InputDataPolicyProtocolsConfig(BaseModel):
158217
Remote: list[str] = []
218+
"""List of protocols that should be considered as remote access methods (e.g., 'https', 'gsiftp', 'srm')."""
159219
Local: list[str] = []
220+
"""List of protocols that should be considered as local access methods (e.g., 'file', 'root')."""
160221

161222

162223
class InputDataPolicyConfig(BaseModel):
163224
# TODO: Remove this once the model is extended to support everything
164-
model_config = ConfigDict(extra="ignore", frozen=True)
225+
model_config = ConfigDict(
226+
extra="ignore", frozen=True, use_attribute_docstrings=True
227+
)
165228

166229
Default: str = "Default = DIRAC.WorkloadManagementSystem.Client.InputDataByProtocol"
230+
"""Default input data access policy. This is the fallback policy when no specific protocol is matched."""
167231
Download: str = "DIRAC.WorkloadManagementSystem.Client.DownloadInputData"
232+
"""Policy for downloading input data files to the local worker node before job execution."""
168233
Protocol: str = "DIRAC.WorkloadManagementSystem.Client.InputDataByProtocol"
234+
"""Policy for accessing input data directly via supported protocols without downloading."""
169235
AllReplicas: bool = True
236+
"""Whether to consider all available replicas when resolving input data locations."""
170237
Protocols: InputDataPolicyProtocolsConfig = InputDataPolicyProtocolsConfig()
238+
"""Protocol-specific configuration defining which protocols are available for remote and local access."""
171239
InputDataModule: str = "DIRAC.Core.Utilities.InputDataResolution"
240+
"""Module responsible for resolving input data locations and determining access methods."""
172241

173242

174243
class OperationsConfig(BaseModel):
175244
EnableSecurityLogging: bool = False
245+
"""Flag for globally disabling the use of the SecurityLogging service.
246+
247+
This is False by default, as should be migrated to use centralized logging.
248+
"""
176249
InputDataPolicy: InputDataPolicyConfig = InputDataPolicyConfig()
250+
"""Specify how jobs access their data. See InputDataResolution documentation for details."""
177251
JobDescription: JobDescriptionConfig = JobDescriptionConfig()
252+
"""Configuration for job description defaults and limits."""
178253
Services: ServicesConfig = ServicesConfig()
254+
"""Configuration for various DIRAC services."""
179255
SoftwareDistModule: str = "LocalSoftwareDist"
256+
"""Module used for software distribution."""
180257

181258
Cloud: MutableMapping[str, Any] | None = None
259+
"""Cloud computing configuration."""
182260
DataConsistency: MutableMapping[str, Any] | None = None
261+
"""Data consistency checking configuration."""
183262
DataManagement: MutableMapping[str, Any] | None = None
263+
"""Data management operations configuration."""
184264
EMail: MutableMapping[str, Any] | None = None
265+
"""Email notification configuration."""
185266
GaudiExecution: MutableMapping[str, Any] | None = None
267+
"""Gaudi framework execution configuration."""
186268
Hospital: MutableMapping[str, Any] | None = None
269+
"""Job recovery and hospital configuration."""
187270
JobScheduling: MutableMapping[str, Any] | None = None
271+
"""Advanced job scheduling configuration."""
188272
JobTypeMapping: MutableMapping[str, Any] | None = None
273+
"""Mapping of job types to execution environments."""
189274
LogFiles: MutableMapping[str, Any] | None = None
275+
"""Log file management configuration."""
190276
LogStorage: MutableMapping[str, Any] | None = None
277+
"""Log storage backend configuration."""
191278
Logging: MutableMapping[str, Any] | None = None
279+
"""General logging configuration."""
192280
Matching: MutableMapping[str, Any] | None = None
281+
"""Job matching configuration."""
193282
MonitoringBackends: MutableMapping[str, Any] | None = None
283+
"""Monitoring backend configuration."""
194284
NagiosConnector: MutableMapping[str, Any] | None = None
285+
"""Nagios monitoring integration configuration."""
195286
Pilot: MutableMapping[str, Any] | None = None
287+
"""Pilot job configuration."""
196288
Productions: MutableMapping[str, Any] | None = None
289+
"""Production management configuration."""
197290
Shares: MutableMapping[str, Any] | None = None
291+
"""Resource sharing configuration."""
198292
Shifter: MutableMapping[str, Any] | None = None
293+
"""Shifter proxy configuration."""
199294
SiteSEMappingByProtocol: MutableMapping[str, Any] | None = None
295+
"""Site storage element mapping by protocol."""
200296
TransformationPlugins: MutableMapping[str, Any] | None = None
297+
"""Data transformation plugin configuration."""
201298
Transformations: MutableMapping[str, Any] | None = None
299+
"""Data transformation system configuration."""
202300
ResourceStatus: MutableMapping[str, Any] | None = None
301+
"""Resource status monitoring configuration."""
203302

204303

205304
class ResourcesComputingConfig(BaseModel):
@@ -209,6 +308,10 @@ class ResourcesComputingConfig(BaseModel):
209308
# TODO: Figure out how to remove this in LHCbDIRAC and then consider
210309
# constraining there to be at least one entry
211310
OSCompatibility: MutableMapping[str, set[str]] = {}
311+
"""Compatibility matrix between DIRAC platforms and OS versions.
312+
313+
Used by SiteDirector to match TaskQueues to Computing Element capabilities.
314+
"""
212315

213316
@field_validator("OSCompatibility", mode="before")
214317
@classmethod
@@ -232,22 +335,34 @@ def ensure_self_compatibility(cls, v: dict[str, set[str]]) -> dict[str, set[str]
232335

233336
class ResourcesConfig(BaseModel):
234337
# TODO: Remove this once the model is extended to support everything
235-
model_config = ConfigDict(extra="ignore", frozen=True)
338+
model_config = ConfigDict(
339+
extra="ignore", frozen=True, use_attribute_docstrings=True
340+
)
236341

237342
Computing: ResourcesComputingConfig = ResourcesComputingConfig()
343+
"""Computing resource configuration."""
238344

239345

240346
class Config(BaseModel):
241347
DIRAC: DIRACConfig
348+
"""The DIRAC section contains general parameters needed in most installation types."""
242349
Operations: MutableMapping[str, OperationsConfig]
350+
"""Operations configuration per VO. The Defaults entry is automatically merged into each VO-specific config."""
243351
Registry: MutableMapping[str, RegistryConfig]
352+
"""Registry sections to register VOs, groups, users and hosts. See UserManagement documentation for details."""
244353
Resources: ResourcesConfig = ResourcesConfig()
354+
"""Resources configuration including computing elements, storage elements, and sites."""
245355

246356
LocalSite: Any = None
357+
"""Local site-specific configuration parameters."""
247358
LogLevel: Any = None
359+
"""Global logging level configuration."""
248360
MCTestingDestination: Any = None
361+
"""Monte Carlo testing destination configuration."""
249362
Systems: Any | None = None
363+
"""Systems configuration."""
250364
WebApp: Any = None
365+
"""Web application configuration parameters."""
251366

252367
@model_validator(mode="before")
253368
@classmethod

0 commit comments

Comments
 (0)