Skip to content

Commit

Permalink
Handling allOf directives in config schemas (#164)
Browse files Browse the repository at this point in the history
In JSON Schema, the `allOf` directive is commonly used to extend a base
schema with new properties. In the case of StreamFlow extensions, all the
nested `allOf` directives should be flattened when users call the
`streamflow ext show` subcommand, in order to display a complete documentation.
  • Loading branch information
GlassOfWhiskey authored Jun 14, 2023
1 parent 7187d56 commit 1987aa9
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
1 change: 1 addition & 0 deletions streamflow/deployment/connector/schemas/flux.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"properties": {
"services": {
"type": "object",
"description": "Map containing named configurations of Flux submissions. Parameters can be either specified as #flux directives in a file or directly in YAML format.",
"patternProperties": {
"^[a-z][a-zA-Z0-9._-]*$": {
"$ref": "#/definitions/service"
Expand Down
1 change: 1 addition & 0 deletions streamflow/deployment/connector/schemas/pbs.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"properties": {
"services": {
"type": "object",
"description": "Map containing named configurations of PBS submissions. Parameters can be either specified as #BSUB directives in a file or directly in YAML format.",
"patternProperties": {
"^[a-z][a-zA-Z0-9._-]*$": {
"$ref": "#/definitions/service"
Expand Down
1 change: 1 addition & 0 deletions streamflow/deployment/connector/schemas/slurm.json
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@
"properties": {
"services": {
"type": "object",
"description": "Map containing named configurations of Slurm submissions. Parameters can be either specified as #SBATCH directives in a file or directly in YAML format.",
"patternProperties": {
"^[a-z][a-zA-Z0-9._-]*$": {
"$ref": "#/definitions/service"
Expand Down
26 changes: 25 additions & 1 deletion streamflow/ext/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ def _filter_by_name(classes: MutableMapping[str, Any], name: str):
return filtered_classes


def _flatten_all_of(entity_schema):
for obj in entity_schema["allOf"]:
if "allOf" in obj:
obj["properties"] = {**_flatten_all_of(obj), **obj.get("properties", {})}
entity_schema["properties"] = {
**obj.get("properties", {}),
**entity_schema.get("properties", {}),
}
del entity_schema["allOf"]
return dict(sorted(entity_schema["properties"].items()))


def _get_property_desc(k: str, obj: MutableMapping[str, Any]) -> str:
property_desc = [k]
if "type" in obj:
Expand All @@ -42,7 +54,17 @@ def _get_property_desc(k: str, obj: MutableMapping[str, Any]) -> str:
def _get_type_repr(obj: MutableMapping[str, Any]) -> str | None:
if "type" in obj:
if obj["type"] == "object":
return obj.get("title", "object")
if "patternProperties" in obj:
if len(obj["patternProperties"]) > 1:
types = [
_get_type_repr(t) for t in obj["patternProperties"].values()
]
type_ = f"Union[{', '.join(types)}]"
else:
type_ = _get_type_repr(list(obj["patternProperties"].values())[0])
return f"Map[str, {type_}]"
else:
return obj.get("title", "object")
else:
return obj["type"]
else:
Expand Down Expand Up @@ -222,6 +244,8 @@ def show_extension(name: str, type_: str):
base_uri=f"file://{os.path.dirname(entity_schema)}/",
jsonschema=True,
)
if "allOf" in entity_schema:
entity_schema["properties"] = _flatten_all_of(entity_schema)
format_string = (
"{:<"
+ str(max(len(name) + 2, 6))
Expand Down

0 comments on commit 1987aa9

Please sign in to comment.