Skip to content

Commit a2a9050

Browse files
committed
fix(models)
- Add additional manfiest model title, example, or description - Begin refactoring models using Annotated field pattern
1 parent d99891a commit a2a9050

File tree

6 files changed

+183
-61
lines changed

6 files changed

+183
-61
lines changed

script/render_jsonschema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# "json-schema-for-humans>=1.5.1",
77
# "lsst-cm-service",
88
# "lsst-utils",
9-
# "pydantic==2.11.*",
9+
# "pydantic==2.12.*",
1010
# ]
1111
#
1212
# [tool.uv.sources]

src/lsst/cmservice/models/manifests/bps.py

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from __future__ import annotations
66

7-
from typing import Any
7+
from typing import Annotated, Any
88

99
from pydantic import Field
1010

@@ -19,46 +19,72 @@ class BpsSpec(ManifestSpec):
1919
"""
2020

2121
model_config = SPEC_CONFIG
22-
pipeline_yaml: str = Field(
23-
description="The absolute path to a Pipeline YAML specification file with optional anchor. "
24-
"The path must begin with a `/` or a `${...}` environment variable.",
25-
pattern="^(/|\\$\\{.*\\})(.*)(\\.yaml)(#.*)?$",
26-
)
22+
pipeline_yaml: (
23+
Annotated[
24+
str,
25+
Field(
26+
title="Pipeline YAML File",
27+
description="The absolute path to a Pipeline YAML specification file with optional anchor. "
28+
"The path must begin with a `/` or a `${...}` environment variable.",
29+
pattern="^(/|\\$\\{.*\\})(.*)(\\.yaml)(#.*)?$",
30+
examples=[
31+
"${DRP_PIPE_DIR}/path/to/pipeline.yaml#anchor",
32+
"/absolute/path/to/file.yaml",
33+
"${CUSTOM_VAR}/file.yaml#anchor1,anchor2",
34+
],
35+
),
36+
]
37+
| Annotated[
38+
None,
39+
Field(
40+
title="No Pipeline YAML",
41+
description="A BPS Manifest does not need to specify a pipeline YAML file, but one is "
42+
"mandatory for a Step.",
43+
),
44+
]
45+
) = None
2746
variables: dict[str, str] | None = Field(
2847
default=None,
29-
description="A mapping of name-value string pairs used to define addtional top-level BPS settings "
48+
title="BPS Variables",
49+
description="A mapping of name-value string pairs used to define additional top-level BPS settings "
3050
"or substitution variables. Note that the values are quoted in the output. For values that should "
3151
"not be quoted or otherwise used literally, see `literals`",
3252
examples=[{"operator": "lsstsvc1"}],
3353
)
3454
include_files: list[str] | None = Field(
3555
default_factory=list,
56+
title="BPS Include Config Files",
3657
description="A list of include files added to the BPS submission file under the `includeConfigs`"
3758
" heading. This list is combined with `include_files` from other manifests.",
3859
examples=[["${CTRL_BPS_DIR}/python/lsst/ctrl/bps/etc/bps_default.yaml"]],
3960
)
4061
literals: dict[str, Any] | None = Field(
4162
default=None,
63+
title="BPS Configuration Literals",
4264
description="A mapping of arbitrary key-value sections to be added as additional literal YAML to "
4365
"the BPS submission file. For setting arbitrary BPS substitution variables, use `variables`. ",
4466
examples=[
4567
{
46-
"requestMemory": 2048,
47-
"numberOfRetries": 5,
48-
"retryUnlessExit": [1, 2],
49-
"finalJob": {"command1": "echo HELLO WORLD"},
68+
"literals": {
69+
"requestMemory": 2048,
70+
"numberOfRetries": 5,
71+
"retryUnlessExit": [1, 2],
72+
"finalJob": {"command1": "echo HELLO WORLD"},
73+
}
5074
}
5175
],
5276
)
5377
environment: dict[str, str] | None = Field(
5478
default=None,
79+
title="BPS Environment Variables",
5580
description="A mapping of name-value string pairs used to defined additional values under the "
5681
"`environment` heading of the BPS submission file.",
5782
min_length=1,
58-
examples=[{"LSST_S3_USE_THREADS": 1}],
83+
examples=[{"environment": {"LSST_S3_USE_THREADS": 1}}],
5984
)
6085
payload: dict[str, str] | None = Field(
6186
default=None,
87+
title="BPS Payload Configuration",
6288
description="A mapping of name-value string pairs used to define BPS payload options. "
6389
"Note that these values are generated from other configuration sources at runtime.",
6490
)
@@ -76,6 +102,7 @@ class BpsSpec(ManifestSpec):
76102
)
77103
clustering: dict[str, Any] | None = Field(
78104
default=None,
105+
title="BPS Clustering Configuration",
79106
description="A mapping of labeled clustering directives, added as literal YAML under the `cluster` "
80107
"heading. The top-level `clusterAlgorithm` should be added to `literals`.",
81108
examples=[
@@ -91,6 +118,7 @@ class BpsSpec(ManifestSpec):
91118
)
92119
operator: str = Field(
93120
default="cmservice",
121+
title="BPS Operator Name",
94122
description="The string name of a pilot or operator to reflect in the BPS configuration.",
95123
)
96124

src/lsst/cmservice/models/manifests/butler.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,33 +54,38 @@ class ButlerCollectionsSpec(BaseModel):
5454
"any ancestor `step_output` collection."
5555
" This is used internally and generally does not need to be configured.",
5656
examples=["{campaign_public_output}/{step}/input"],
57+
json_schema_extra={"readOnly": True},
5758
)
5859
step_output: str | None = Field(
5960
default=None,
6061
description="The *chained* output collection for a step, usually consisting of each step-group's "
6162
"`run` collection."
6263
" This is used internally and generally does not need to be configured.",
6364
examples=["{campaign_public_output}/{step}_output"],
65+
json_schema_extra={"readOnly": True},
6466
)
6567
step_public_output: str | None = Field(
6668
default=None,
6769
description="The *chained* output collection that includes the `step_output` and additional step "
6870
"and/or campaign inputs."
6971
" This is used internally and generally does not need to be configured.",
7072
examples=["{campaign_public_output}/{step}"],
73+
json_schema_extra={"readOnly": True},
7174
)
7275
group_output: str | None = Field(
7376
default=None,
7477
description="A collection name associated with the `payload.output` BPS setting."
7578
" This is used internally and generally does not need to be configured.",
7679
examples=["{campaign_public_output}/{step}/{group_nonce}", "u/{operator}/{payloadName}"],
80+
json_schema_extra={"readOnly": True},
7781
)
7882
run: str | None = Field(
7983
default=None,
8084
description="The run collection created by a group's execution (the `payload.outputRun` BPS setting)."
8185
" This is used internally and generally does not need to be configured.",
8286
examples=["{out}/{step}/{group}/{job}"],
8387
validation_alias=AliasChoices("job_run", "run"),
88+
json_schema_extra={"readOnly": True},
8489
)
8590

8691

src/lsst/cmservice/models/manifests/facility.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ class FacilitySpec(ManifestSpec):
1717
model_config = SPEC_CONFIG | {"title": "site_spec"}
1818
facility: Literal["USDF", "IN2P3", "LANC", "RAL"] = Field(
1919
default="USDF",
20+
title="Processing Facility Name",
2021
description="The name of the processing facility.",
2122
examples=["USDF", "IN2P3"],
2223
)
2324
include_files: list[str] = Field(
2425
default_factory=list,
26+
title="Facility-Specific BPS Include Files",
2527
description="A list of files to be added to the BPS submission as include files "
2628
"that are specific to the use of this Facility.",
2729
examples=[["${DRP_PIPE_DIR}/bps/caching/{instrument}/{site}/{caching}.yaml"]],

src/lsst/cmservice/models/manifests/lsst.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,63 @@ class LsstSpec(ManifestSpec):
1818
model_config = SPEC_CONFIG
1919
lsst_version: str = Field(
2020
default="w_latest",
21+
title="Stack Version",
2122
description="LSST Stack version or tag",
2223
examples=["w_latest", "d_latest", "w_2026_01"],
2324
)
2425
lsst_distrib_dir: str = Field(
26+
title="LSST Distribution Directory",
2527
description="Absolute path to a stack distribution location",
2628
examples=["/sdf/group/rubin/sw/tag/<tag>", "/cvmfs/sw.lsst.eu/linux-x86_64/lsst_distrib/<tag>/"],
2729
)
2830
prepend: str | None = Field(
2931
default=None,
32+
title="Stack Setup Prepend Commands",
3033
description="A newline-delimited string of shell actions to execute prior to stack setup.",
3134
examples=["echo Hello World", "echo Starting New Campaign\necho Hello World"],
3235
)
3336
custom_lsst_setup: str | None = Field(
3437
default=None,
38+
title="Custom Stack Setup Commands",
3539
description="A newline-delimited string of optional commands to be added to any Bash script that "
3640
"sets up the LSST Stack, to be executed verbatim *after* EUPS setup but *before* the payload "
3741
"command. Can be used to customize the Stack with EUPS, for example.",
3842
examples=["setup --just --root=/path/to/custom/product"],
3943
)
4044
append: str | None = Field(
4145
default=None,
46+
title="Stack Setup Append Commands",
4247
description="A newline-delimited string of shell actions to execute after the payload command.",
4348
examples=["echo Finished", "source /path/to/custom/script.sh"],
4449
)
4550
environment: Mapping | None = Field(
4651
default_factory=dict,
52+
title="Stack Setup Environment Variables",
4753
description="A mapping of environment variables to set prior to stack setup",
4854
min_length=1,
49-
examples=[{"LSST_USE_OPTIONAL_FEATURE": 1}],
55+
examples=[{"environment": {"LSST_USE_OPTIONAL_FEATURE": 1}}],
5056
)
5157
ticket: str | None = Field(
5258
default=None,
59+
title="Ticket Number",
5360
description="An optional JIRA ticket number associated with the campaign.",
54-
examples=["DM-XXXXX"],
61+
examples=[{"ticket": "DM-XXXXX"}],
5562
)
5663
description: str | None = Field(
5764
default=None,
65+
title="Campaign Description",
5866
description="An optional description of the campaign.",
5967
examples=["An optional description of the campaign."],
6068
)
6169
campaign: str | None = Field(
6270
default=None,
71+
title="Campaign Name",
6372
description="An optional name for the campaign.",
6473
examples=["CustomCampaign"],
6574
)
6675
project: str | None = Field(
6776
default=None,
77+
title="Campaign Project or Epic",
6878
description="An optional project name or identifier associated with the campaign.",
6979
examples=["My special campaign", "Daily batch processing"],
7080
)

0 commit comments

Comments
 (0)