Skip to content

Commit ccb1f48

Browse files
authored
docs: settings documentation using settings-doc markdown generator (#698)
* docs: settings doc fix: annoying wrapper script docs: fix task doc fix: add ci skip settings-doc-check * docs: env variable / settings documentation generator fix: cleanups * fix: use separate tooling env for settings-doc fix: well that didn't work fix: update tasks fix: format settings doc files
1 parent 26c86fa commit ccb1f48

12 files changed

Lines changed: 818 additions & 50 deletions

File tree

.github/workflows/generate_pixi_tasks_doc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def get_task_group(task_name):
1818
return "Client Generation"
1919
if task_name == "shellcheck":
2020
return "Shellcheck"
21+
if task_name.startswith("generate-settings-"):
22+
return "Settings"
2123
return "Default"
2224

2325

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,7 @@ docs/source/_build
9696
.pixi
9797
pixi.lock
9898
*.egg-info
99+
docs/templates/_builtin_markdown.jinja
100+
101+
# docs site
102+
site

.pre-commit-config.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ default_language_version:
88
python: python3
99

1010
ci:
11-
skip: [generate-pixi-docs]
11+
skip: [generate-pixi-docs, settings-doc-check]
1212

1313
default_stages: [pre-commit]
1414

@@ -85,3 +85,12 @@ repos:
8585
language: system
8686
pass_filenames: false
8787
files: ^pixi\.toml$|^pixi\.lock$ # only run if pixi files change
88+
89+
- repo: local
90+
hooks:
91+
- id: settings-doc-check
92+
name: Generate settings documentation
93+
entry: pixi run -e default python scripts/generate_settings_docs.py
94+
language: system
95+
pass_filenames: false
96+
files: ^(diracx-.*/src/diracx/.*/settings\.py|docs/.*\.j2|docs/templates/.*\.jinja|scripts/generate_settings_docs\.py)$

diracx-core/src/diracx/core/settings.py

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,16 @@ async def lifetime_function(self) -> AsyncIterator[None]:
132132
class DevelopmentSettings(ServiceSettingsBase):
133133
"""Settings for the Development Configuration that can influence run time."""
134134

135-
model_config = SettingsConfigDict(env_prefix="DIRACX_DEV_")
135+
model_config = SettingsConfigDict(
136+
env_prefix="DIRACX_DEV_", use_attribute_docstrings=True
137+
)
136138

137-
# When then to true (only for demo/CI), crash if an access policy isn't
138-
# called
139139
crash_on_missed_access_policy: bool = False
140+
"""When set to true (only for demo/CI), crash if an access policy isn't called.
141+
142+
This is useful for development and testing to ensure all endpoints have proper
143+
access control policies defined.
144+
"""
140145

141146
@classmethod
142147
def create(cls) -> Self:
@@ -146,39 +151,123 @@ def create(cls) -> Self:
146151
class AuthSettings(ServiceSettingsBase):
147152
"""Settings for the authentication service."""
148153

149-
model_config = SettingsConfigDict(env_prefix="DIRACX_SERVICE_AUTH_")
154+
model_config = SettingsConfigDict(
155+
env_prefix="DIRACX_SERVICE_AUTH_", use_attribute_docstrings=True
156+
)
150157

151158
dirac_client_id: str = "myDIRACClientID"
152-
# TODO: This should be taken dynamically
153-
# ["http://pclhcb211:8000/docs/oauth2-redirect"]
159+
"""OAuth2 client identifier for DIRAC services.
160+
161+
This should match the client ID registered with the identity provider.
162+
"""
163+
154164
allowed_redirects: list[str] = []
165+
"""List of allowed redirect URLs for OAuth2 authorization flow.
166+
167+
These URLs must be pre-registered and should match the redirect URIs
168+
configured in the OAuth2 client registration.
169+
Example: ["http://localhost:8000/docs/oauth2-redirect"]
170+
"""
171+
155172
device_flow_expiration_seconds: int = 600
173+
"""Expiration time in seconds for device flow authorization requests.
174+
175+
After this time, the device code becomes invalid and users must restart
176+
the device flow process. Default: 10 minutes.
177+
"""
178+
156179
authorization_flow_expiration_seconds: int = 300
180+
"""Expiration time in seconds for authorization code flow.
181+
182+
The time window during which the authorization code remains valid
183+
before it must be exchanged for tokens. Default: 5 minutes.
184+
"""
157185

158-
# State key is used to encrypt/decrypt the state dict passed to the IAM
159186
state_key: FernetKey
187+
"""Encryption key used to encrypt/decrypt the state parameter passed to the IAM.
188+
189+
This key ensures the integrity and confidentiality of state information
190+
during OAuth2 flows. Must be a valid Fernet key.
191+
"""
160192

161193
token_issuer: str
194+
"""The issuer identifier for JWT tokens.
195+
196+
This should be a URI that uniquely identifies the token issuer and
197+
matches the 'iss' claim in issued JWT tokens.
198+
"""
199+
162200
token_keystore: TokenSigningKeyStore
201+
"""Keystore containing the cryptographic keys used for signing JWT tokens.
202+
203+
This includes both public and private keys for token signature
204+
generation and verification.
205+
"""
206+
163207
token_allowed_algorithms: list[str] = ["RS256", "EdDSA"] # noqa: S105
208+
"""List of allowed cryptographic algorithms for JWT token signing.
209+
210+
Supported algorithms include RS256 (RSA with SHA-256) and EdDSA
211+
(Edwards-curve Digital Signature Algorithm). Default: ["RS256", "EdDSA"]
212+
"""
213+
164214
access_token_expire_minutes: int = 20
215+
"""Expiration time in minutes for access tokens.
216+
217+
After this duration, access tokens become invalid and must be refreshed
218+
or re-obtained. Default: 20 minutes.
219+
"""
220+
165221
refresh_token_expire_minutes: int = 60
222+
"""Expiration time in minutes for refresh tokens.
223+
224+
The maximum lifetime of refresh tokens before they must be re-issued
225+
through a new authentication flow. Default: 60 minutes.
226+
"""
166227

167228
available_properties: set[SecurityProperty] = Field(
168229
default_factory=SecurityProperty.available_properties
169230
)
231+
"""Set of security properties available in this DIRAC installation.
232+
233+
These properties define various authorization capabilities and are used
234+
for access control decisions. Defaults to all available security properties.
235+
"""
170236

171237

172238
class SandboxStoreSettings(ServiceSettingsBase):
173239
"""Settings for the sandbox store."""
174240

175-
model_config = SettingsConfigDict(env_prefix="DIRACX_SANDBOX_STORE_")
241+
model_config = SettingsConfigDict(
242+
env_prefix="DIRACX_SANDBOX_STORE_", use_attribute_docstrings=True
243+
)
176244

177245
bucket_name: str
246+
"""Name of the S3 bucket used for storing job sandboxes.
247+
248+
This bucket will contain input and output sandbox files for DIRAC jobs.
249+
The bucket must exist or auto_create_bucket must be enabled.
250+
"""
251+
178252
s3_client_kwargs: dict[str, Any]
253+
"""Configuration parameters passed to the S3 client."""
254+
179255
auto_create_bucket: bool = False
256+
"""Whether to automatically create the S3 bucket if it doesn't exist."""
257+
180258
url_validity_seconds: int = 5 * 60
259+
"""Validity duration in seconds for pre-signed S3 URLs.
260+
261+
This determines how long generated download/upload URLs remain valid
262+
before expiring. Default: 300 seconds (5 minutes).
263+
"""
264+
181265
se_name: str = "SandboxSE"
266+
"""Logical name of the Storage Element for the sandbox store.
267+
268+
This name is used within DIRAC to refer to this sandbox storage
269+
endpoint in job descriptions and file catalogs.
270+
"""
182271
_client: S3Client = PrivateAttr()
183272

184273
@contextlib.asynccontextmanager
Lines changed: 171 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,173 @@
11
# List of environment variables
22

3-
## Core
4-
5-
- `DIRACX_CONFIG_BACKEND_URL`: The URL of the configuration backend.
6-
7-
## Services:
8-
9-
- `DIRACX_SERVICE_AUTH_TOKEN_ISSUER`: The issuer for the auth tokens.
10-
- `DIRACX_SERVICE_AUTH_ALLOWED_REDIRECTS`: A JSON-encoded list of allowed redirect URIs for the authorization code
11-
flow.
12-
- `DIRACX_SERVICE_AUTH_DEVICE_FLOW_EXPIRATION_SECONDS`: The expiration time for the device flow in seconds.
13-
- `DIRACX_SERVICE_AUTH_AUTHORIZATION_FLOW_EXPIRATION_SECONDS`: The expiration time for the authorization flow in
14-
seconds.
15-
- `DIRACX_SERVICE_AUTH_STATE_KEY`: The key used to encrypt the state in the authorization code flow.
16-
- `DIRACX_SERVICE_AUTH_TOKEN_KEYSTORE`: The path to the JWKS file containing the token signing keys.
17-
- `DIRACX_SERVICE_AUTH_TOKEN_ALLOWED_ALGORITHMS`: A JSON-encoded list of allowed algorithms for token signing.
18-
- `DIRACX_SERVICE_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES`: The expiration time for the access token in minutes.
19-
- `DIRACX_SERVICE_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES`: The expiration time for the refresh token in minutes.
20-
- `DIRACX_SANDBOX_STORE_BUCKET_NAME`: The name of the S3 bucket for the sandbox store.
21-
- `DIRACX_SANDBOX_STORE_S3_CLIENT_KWARGS`: A JSON-encoded dictionary of keyword arguments for the S3 client.
22-
- `DIRACX_SANDBOX_STORE_AUTO_CREATE_BUCKET`: Whether to automatically create the S3 bucket if it doesn't exist.
23-
- `DIRACX_SANDBOX_STORE_URL_VALIDITY_SECONDS`: The validity of the presigned URLs for the sandbox store in seconds.
24-
- `DIRACX_SANDBOX_STORE_SE_NAME`: The name of the storage element for the sandbox store.
25-
- `DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY`: The hashed API key for the legacy exchange endpoint.
26-
- `DIRACX_SERVICE_JOBS_ENABLED`: Whether the jobs service is enabled.
27-
28-
## Databases:
29-
30-
- `DIRACX_DB_URL_<db_name>`: The URL for the SQL database `<db_name>`.
31-
- `DIRACX_OS_DB_<db_name>`: A JSON-encoded dictionary of connection keyword arguments for the OpenSearch database `<db_name>`
32-
33-
## OTEL:
34-
35-
- `DIRACX_OTEL_ENABLED`: Whether OpenTelemetry is enabled.
36-
- `DIRACX_OTEL_APPLICATION_NAME`: The name of the application for OpenTelemetry.
37-
- `DIRACX_OTEL_GRPC_ENDPOINT`: The gRPC endpoint for the OpenTelemetry collector.
38-
- `DIRACX_OTEL_GRPC_INSECURE`: Whether to use an insecure gRPC connection for the OpenTelemetry collector.
39-
- `DIRACX_OTEL_HEADERS`: A JSON-encoded dictionary of headers to pass to the OpenTelemetry collector.
3+
*This page is auto-generated from the settings classes in `diracx.core.settings`.*
4+
5+
## AuthSettings
6+
7+
Settings for the authentication service.
8+
9+
### `DIRACX_SERVICE_AUTH_DIRAC_CLIENT_ID`
10+
11+
*Optional*, default value: `myDIRACClientID`
12+
13+
OAuth2 client identifier for DIRAC services.
14+
15+
This should match the client ID registered with the identity provider.
16+
17+
### `DIRACX_SERVICE_AUTH_ALLOWED_REDIRECTS`
18+
19+
*Optional*, default value: `[]`
20+
21+
List of allowed redirect URLs for OAuth2 authorization flow.
22+
23+
These URLs must be pre-registered and should match the redirect URIs
24+
configured in the OAuth2 client registration.
25+
Example: ["http://localhost:8000/docs/oauth2-redirect"]
26+
27+
### `DIRACX_SERVICE_AUTH_DEVICE_FLOW_EXPIRATION_SECONDS`
28+
29+
*Optional*, default value: `600`
30+
31+
Expiration time in seconds for device flow authorization requests.
32+
33+
After this time, the device code becomes invalid and users must restart
34+
the device flow process. Default: 10 minutes.
35+
36+
### `DIRACX_SERVICE_AUTH_AUTHORIZATION_FLOW_EXPIRATION_SECONDS`
37+
38+
*Optional*, default value: `300`
39+
40+
Expiration time in seconds for authorization code flow.
41+
42+
The time window during which the authorization code remains valid
43+
before it must be exchanged for tokens. Default: 5 minutes.
44+
45+
### `DIRACX_SERVICE_AUTH_STATE_KEY`
46+
47+
**Required**
48+
49+
Encryption key used to encrypt/decrypt the state parameter passed to the IAM.
50+
51+
This key ensures the integrity and confidentiality of state information
52+
during OAuth2 flows. Must be a valid Fernet key.
53+
54+
### `DIRACX_SERVICE_AUTH_TOKEN_ISSUER`
55+
56+
**Required**
57+
58+
The issuer identifier for JWT tokens.
59+
60+
This should be a URI that uniquely identifies the token issuer and
61+
matches the 'iss' claim in issued JWT tokens.
62+
63+
### `DIRACX_SERVICE_AUTH_TOKEN_KEYSTORE`
64+
65+
**Required**
66+
67+
Keystore containing the cryptographic keys used for signing JWT tokens.
68+
69+
This includes both public and private keys for token signature
70+
generation and verification.
71+
72+
### `DIRACX_SERVICE_AUTH_TOKEN_ALLOWED_ALGORITHMS`
73+
74+
*Optional*, default value: `['RS256', 'EdDSA']`
75+
76+
List of allowed cryptographic algorithms for JWT token signing.
77+
78+
Supported algorithms include RS256 (RSA with SHA-256) and EdDSA
79+
(Edwards-curve Digital Signature Algorithm). Default: ["RS256", "EdDSA"]
80+
81+
### `DIRACX_SERVICE_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES`
82+
83+
*Optional*, default value: `20`
84+
85+
Expiration time in minutes for access tokens.
86+
87+
After this duration, access tokens become invalid and must be refreshed
88+
or re-obtained. Default: 20 minutes.
89+
90+
### `DIRACX_SERVICE_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES`
91+
92+
*Optional*, default value: `60`
93+
94+
Expiration time in minutes for refresh tokens.
95+
96+
The maximum lifetime of refresh tokens before they must be re-issued
97+
through a new authentication flow. Default: 60 minutes.
98+
99+
### `DIRACX_SERVICE_AUTH_AVAILABLE_PROPERTIES`
100+
101+
*Optional*
102+
103+
Set of security properties available in this DIRAC installation.
104+
105+
These properties define various authorization capabilities and are used
106+
for access control decisions. Defaults to all available security properties.
107+
108+
## SandboxStoreSettings
109+
110+
Settings for the sandbox store.
111+
112+
### `DIRACX_SANDBOX_STORE_BUCKET_NAME`
113+
114+
**Required**
115+
116+
Name of the S3 bucket used for storing job sandboxes.
117+
118+
This bucket will contain input and output sandbox files for DIRAC jobs.
119+
The bucket must exist or auto_create_bucket must be enabled.
120+
121+
### `DIRACX_SANDBOX_STORE_S3_CLIENT_KWARGS`
122+
123+
**Required**
124+
125+
Configuration parameters passed to the S3 client.
126+
127+
### `DIRACX_SANDBOX_STORE_AUTO_CREATE_BUCKET`
128+
129+
*Optional*, default value: `False`
130+
131+
Whether to automatically create the S3 bucket if it doesn't exist.
132+
133+
### `DIRACX_SANDBOX_STORE_URL_VALIDITY_SECONDS`
134+
135+
*Optional*, default value: `300`
136+
137+
Validity duration in seconds for pre-signed S3 URLs.
138+
139+
This determines how long generated download/upload URLs remain valid
140+
before expiring. Default: 300 seconds (5 minutes).
141+
142+
### `DIRACX_SANDBOX_STORE_SE_NAME`
143+
144+
*Optional*, default value: `SandboxSE`
145+
146+
Logical name of the Storage Element for the sandbox store.
147+
148+
This name is used within DIRAC to refer to this sandbox storage
149+
endpoint in job descriptions and file catalogs.
150+
151+
## OTELSettings
152+
153+
Settings for the Open Telemetry Configuration.
154+
155+
### `DIRACX_OTEL_ENABLED`
156+
157+
*Optional*, default value: `False`
158+
159+
### `DIRACX_OTEL_APPLICATION_NAME`
160+
161+
*Optional*, default value: `diracx`
162+
163+
### `DIRACX_OTEL_GRPC_ENDPOINT`
164+
165+
*Optional*, default value: \`\`
166+
167+
### `DIRACX_OTEL_GRPC_INSECURE`
168+
169+
*Optional*, default value: `True`
170+
171+
### `DIRACX_OTEL_HEADERS`
172+
173+
*Optional*, default value: `None`

0 commit comments

Comments
 (0)