From 4598584b3a3fca2c5583fccfaade847e0f1c50bc Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Mon, 13 Jan 2025 09:11:13 +0000 Subject: [PATCH] Maintained parent class `Partial` in jsonschema --- src/event_model/__init__.py | 9 +- src/event_model/basemodels/datum.py | 2 +- src/event_model/basemodels/datum_page.py | 2 +- src/event_model/basemodels/event.py | 4 +- .../basemodels/event_descriptor.py | 11 +- src/event_model/basemodels/event_page.py | 4 +- src/event_model/basemodels/resource.py | 4 +- src/event_model/basemodels/run_start.py | 4 +- src/event_model/basemodels/run_stop.py | 1 + src/event_model/basemodels/stream_datum.py | 7 +- src/event_model/basemodels/stream_resource.py | 7 +- src/event_model/documents/__init__.py | 9 -- src/event_model/documents/event.py | 29 +++-- src/event_model/documents/event_page.py | 29 +++-- src/event_model/documents/partial_event.py | 28 ----- .../documents/partial_event_page.py | 28 ----- src/event_model/documents/partial_resource.py | 30 ----- src/event_model/documents/resource.py | 31 ++--- src/event_model/generate/create_documents.py | 83 +++++++++---- src/event_model/schemas/datum.json | 2 +- src/event_model/schemas/datum_page.json | 2 +- src/event_model/schemas/event.json | 85 +++++++------ src/event_model/schemas/event_descriptor.json | 2 +- src/event_model/schemas/event_page.json | 115 ++++++++++-------- src/event_model/schemas/partial_event.json | 42 ------- .../schemas/partial_event_page.json | 57 --------- src/event_model/schemas/partial_resource.json | 39 ------ src/event_model/schemas/resource.json | 82 +++++++------ src/event_model/schemas/run_start.json | 2 +- src/event_model/schemas/run_stop.json | 2 +- src/event_model/schemas/stream_datum.json | 5 +- src/event_model/schemas/stream_resource.json | 5 +- 32 files changed, 320 insertions(+), 442 deletions(-) delete mode 100644 src/event_model/documents/partial_event.py delete mode 100644 src/event_model/documents/partial_event_page.py delete mode 100644 src/event_model/documents/partial_resource.py delete mode 100644 src/event_model/schemas/partial_event.json delete mode 100644 src/event_model/schemas/partial_event_page.json delete mode 100644 src/event_model/schemas/partial_resource.json diff --git a/src/event_model/__init__.py b/src/event_model/__init__.py index b6bf6b9fa..f497f919f 100644 --- a/src/event_model/__init__.py +++ b/src/event_model/__init__.py @@ -35,7 +35,7 @@ from .documents.datum import Datum from .documents.datum_page import DatumPage -from .documents.event import Event +from .documents.event import Event, PartialEvent from .documents.event_descriptor import ( Configuration, DataKey, @@ -44,11 +44,8 @@ LimitsRange, PerObjectHint, ) -from .documents.event_page import EventPage -from .documents.partial_event import PartialEvent -from .documents.partial_event_page import PartialEventPage -from .documents.partial_resource import PartialResource -from .documents.resource import Resource +from .documents.event_page import EventPage, PartialEventPage +from .documents.resource import PartialResource, Resource from .documents.run_start import ( CalculatedEventProjection, Calculation, diff --git a/src/event_model/basemodels/datum.py b/src/event_model/basemodels/datum.py index ef863da16..02b300707 100644 --- a/src/event_model/basemodels/datum.py +++ b/src/event_model/basemodels/datum.py @@ -11,7 +11,7 @@ class Datum(BaseModel): """Document to reference a quanta of externally-stored data""" - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="datum", extra="forbid") datum_id: Annotated[ str, diff --git a/src/event_model/basemodels/datum_page.py b/src/event_model/basemodels/datum_page.py index ca26f12e4..1df7565be 100644 --- a/src/event_model/basemodels/datum_page.py +++ b/src/event_model/basemodels/datum_page.py @@ -11,7 +11,7 @@ class DataFrameForDatumPage(RootModel): class DatumPage(BaseModel): """Page of documents to reference a quanta of externally-stored data""" - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="datum_page", extra="forbid") datum_id: Annotated[ DataFrameForDatumPage, diff --git a/src/event_model/basemodels/event.py b/src/event_model/basemodels/event.py index 120a83da4..d003ccfbf 100644 --- a/src/event_model/basemodels/event.py +++ b/src/event_model/basemodels/event.py @@ -5,7 +5,7 @@ class PartialEvent(BaseModel): - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="partial_event", extra="forbid") data: Annotated[Dict[str, Any], Field(description="The actual measurement data")] filled: Annotated[ @@ -33,7 +33,7 @@ class PartialEvent(BaseModel): class Event(PartialEvent): """Document to record a quanta of collected data""" - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="event", extra="forbid") descriptor: Annotated[ str, Field(description="UID of the EventDescriptor to which this Event belongs") diff --git a/src/event_model/basemodels/event_descriptor.py b/src/event_model/basemodels/event_descriptor.py index 9dacc855f..5432efbf5 100644 --- a/src/event_model/basemodels/event_descriptor.py +++ b/src/event_model/basemodels/event_descriptor.py @@ -118,7 +118,12 @@ class DataKey(BaseModel): Limits, Field( default_factory=lambda: Limits( - control=None, display=None, warning=None, alarm=None + control=None, + display=None, + warning=None, + alarm=None, + hysteresis=None, + rds=None, ), description="Epics limits.", ), @@ -251,7 +256,9 @@ class EventDescriptor(BaseModel): documents""" model_config = ConfigDict( - extra="allow", json_schema_extra=EVENT_DESCRIPTOR_EXTRA_SCHEMA + title="event_descriptor", + extra="allow", + json_schema_extra=EVENT_DESCRIPTOR_EXTRA_SCHEMA, ) configuration: Annotated[ diff --git a/src/event_model/basemodels/event_page.py b/src/event_model/basemodels/event_page.py index 3cb5d38e4..d73aac40c 100644 --- a/src/event_model/basemodels/event_page.py +++ b/src/event_model/basemodels/event_page.py @@ -12,7 +12,7 @@ class PartialEventPage(BaseModel): - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="partial_event_page", extra="forbid") data: Annotated[ DataFrameForEventPage, @@ -44,7 +44,7 @@ class PartialEventPage(BaseModel): class EventPage(PartialEventPage): """Page of documents to record a quanta of collected data""" - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="event_page", extra="forbid") descriptor: Annotated[ str, diff --git a/src/event_model/basemodels/resource.py b/src/event_model/basemodels/resource.py index 6f4657d55..c99dbde61 100644 --- a/src/event_model/basemodels/resource.py +++ b/src/event_model/basemodels/resource.py @@ -5,7 +5,7 @@ class PartialResource(BaseModel): - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="partial_resource", extra="forbid") spec: Annotated[ str, @@ -41,7 +41,7 @@ class Resource(PartialResource): externally-stored data """ - model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(title="resource", extra="forbid") path_semantics: Annotated[ Literal["posix", "windows"], diff --git a/src/event_model/basemodels/run_start.py b/src/event_model/basemodels/run_start.py index 17767c0e0..abb5f2f70 100644 --- a/src/event_model/basemodels/run_start.py +++ b/src/event_model/basemodels/run_start.py @@ -192,7 +192,9 @@ class RunStart(BaseModel): later documents link to it """ - model_config = ConfigDict(extra="allow", json_schema_extra=RUN_START_EXTRA_SCHEMA) + model_config = ConfigDict( + title="run_start", extra="allow", json_schema_extra=RUN_START_EXTRA_SCHEMA + ) data_groups: Annotated[ List[str], diff --git a/src/event_model/basemodels/run_stop.py b/src/event_model/basemodels/run_stop.py index 590737c98..35585dc35 100644 --- a/src/event_model/basemodels/run_stop.py +++ b/src/event_model/basemodels/run_stop.py @@ -45,6 +45,7 @@ class RunStop(BaseModel): """ model_config = ConfigDict( + title="run_stop", extra="allow", json_schema_extra=RUN_STOP_EXTRA_SCHEMA, ) diff --git a/src/event_model/basemodels/stream_datum.py b/src/event_model/basemodels/stream_datum.py index 5a7eea287..c6f24aa20 100644 --- a/src/event_model/basemodels/stream_datum.py +++ b/src/event_model/basemodels/stream_datum.py @@ -1,6 +1,6 @@ from typing import Any -from pydantic import BaseModel, Field, RootModel +from pydantic import BaseModel, ConfigDict, Field, RootModel from typing_extensions import Annotated @@ -24,6 +24,11 @@ class StreamRange(BaseModel): class StreamDatum(BaseModel): """Document to reference a quanta of an externally-stored stream of data.""" + model_config = ConfigDict( + title="stream_datum", + extra="allow", + ) + descriptor: Annotated[ str, Field(description="UID of the EventDescriptor to which this Datum belongs"), diff --git a/src/event_model/basemodels/stream_resource.py b/src/event_model/basemodels/stream_resource.py index 7a9e9aa43..c8cc9f7ed 100644 --- a/src/event_model/basemodels/stream_resource.py +++ b/src/event_model/basemodels/stream_resource.py @@ -1,6 +1,6 @@ from typing import Any, Dict -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from typing_extensions import Annotated @@ -10,6 +10,11 @@ class StreamResource(BaseModel): externally-stored data streams """ + model_config = ConfigDict( + title="stream_resource", + extra="allow", + ) + data_key: Annotated[ str, Field( diff --git a/src/event_model/documents/__init__.py b/src/event_model/documents/__init__.py index 72e7e72b5..6266c3c8a 100644 --- a/src/event_model/documents/__init__.py +++ b/src/event_model/documents/__init__.py @@ -7,9 +7,6 @@ from .event import * # noqa: F403 from .event_descriptor import * # noqa: F403 from .event_page import * # noqa: F403 -from .partial_event import * # noqa: F403 -from .partial_event_page import * # noqa: F403 -from .partial_resource import * # noqa: F403 from .resource import * # noqa: F403 from .run_start import * # noqa: F403 from .run_stop import * # noqa: F403 @@ -22,9 +19,6 @@ Type[Event], # noqa: F405, Type[EventDescriptor], # noqa: F405, Type[EventPage], # noqa: F405, - Type[PartialEvent], # noqa: F405, - Type[PartialEventPage], # noqa: F405, - Type[PartialResource], # noqa: F405, Type[Resource], # noqa: F405, Type[RunStart], # noqa: F405, Type[RunStop], # noqa: F405, @@ -38,9 +32,6 @@ Event, # noqa: F405 EventDescriptor, # noqa: F405 EventPage, # noqa: F405 - PartialEvent, # noqa: F405 - PartialEventPage, # noqa: F405 - PartialResource, # noqa: F405 Resource, # noqa: F405 RunStart, # noqa: F405 RunStop, # noqa: F405 diff --git a/src/event_model/documents/event.py b/src/event_model/documents/event.py index cc246aacb..c33a99607 100644 --- a/src/event_model/documents/event.py +++ b/src/event_model/documents/event.py @@ -9,27 +9,15 @@ from typing_extensions import NotRequired -class Event(TypedDict): - """ - Document to record a quanta of collected data - """ - +class PartialEvent(TypedDict): data: Dict[str, Any] """ The actual measurement data """ - descriptor: str - """ - UID of the EventDescriptor to which this Event belongs - """ filled: NotRequired[Dict[str, Union[bool, str]]] """ Mapping each of the keys of externally-stored data to the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded) """ - seq_num: int - """ - Sequence number to identify the location of this Event in the Event stream - """ time: float """ The event time. This maybe different than the timestamps on each of the data entries. @@ -38,6 +26,21 @@ class Event(TypedDict): """ The timestamps of the individual measurement data """ + + +class Event(PartialEvent): + """ + Document to record a quanta of collected data + """ + + descriptor: str + """ + UID of the EventDescriptor to which this Event belongs + """ + seq_num: int + """ + Sequence number to identify the location of this Event in the Event stream + """ uid: str """ Globally unique identifier for this Event diff --git a/src/event_model/documents/event_page.py b/src/event_model/documents/event_page.py index 3d963f8ba..a9ce07f34 100644 --- a/src/event_model/documents/event_page.py +++ b/src/event_model/documents/event_page.py @@ -9,27 +9,15 @@ from typing_extensions import NotRequired -class EventPage(TypedDict): - """ - Page of documents to record a quanta of collected data - """ - +class PartialEventPage(TypedDict): data: Dict[str, List] """ The actual measurement data """ - descriptor: str - """ - The UID of the EventDescriptor to which all of the Events in this page belong - """ filled: NotRequired[Dict[str, List[Union[bool, str]]]] """ Mapping each of the keys of externally-stored data to an array containing the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded) """ - seq_num: List[int] - """ - Array of sequence numbers to identify the location of each Event in the Event stream - """ time: List[float] """ Array of Event times. This maybe different than the timestamps on each of the data entries @@ -38,6 +26,21 @@ class EventPage(TypedDict): """ The timestamps of the individual measurement data """ + + +class EventPage(PartialEventPage): + """ + Page of documents to record a quanta of collected data + """ + + descriptor: str + """ + The UID of the EventDescriptor to which all of the Events in this page belong + """ + seq_num: List[int] + """ + Array of sequence numbers to identify the location of each Event in the Event stream + """ uid: List[str] """ Array of globally unique identifiers for each Event diff --git a/src/event_model/documents/partial_event.py b/src/event_model/documents/partial_event.py deleted file mode 100644 index cd560f82d..000000000 --- a/src/event_model/documents/partial_event.py +++ /dev/null @@ -1,28 +0,0 @@ -# ruff: noqa -# generated by datamodel-codegen: -# filename: partial_event.json - -from __future__ import annotations - -from typing import Any, Dict, TypedDict, Union - -from typing_extensions import NotRequired - - -class PartialEvent(TypedDict): - data: Dict[str, Any] - """ - The actual measurement data - """ - filled: NotRequired[Dict[str, Union[bool, str]]] - """ - Mapping each of the keys of externally-stored data to the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded) - """ - time: float - """ - The event time. This maybe different than the timestamps on each of the data entries. - """ - timestamps: Dict[str, Any] - """ - The timestamps of the individual measurement data - """ diff --git a/src/event_model/documents/partial_event_page.py b/src/event_model/documents/partial_event_page.py deleted file mode 100644 index fc946bbae..000000000 --- a/src/event_model/documents/partial_event_page.py +++ /dev/null @@ -1,28 +0,0 @@ -# ruff: noqa -# generated by datamodel-codegen: -# filename: partial_event_page.json - -from __future__ import annotations - -from typing import Dict, List, TypedDict, Union - -from typing_extensions import NotRequired - - -class PartialEventPage(TypedDict): - data: Dict[str, List] - """ - The actual measurement data - """ - filled: NotRequired[Dict[str, List[Union[bool, str]]]] - """ - Mapping each of the keys of externally-stored data to an array containing the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded) - """ - time: List[float] - """ - Array of Event times. This maybe different than the timestamps on each of the data entries - """ - timestamps: Dict[str, List] - """ - The timestamps of the individual measurement data - """ diff --git a/src/event_model/documents/partial_resource.py b/src/event_model/documents/partial_resource.py deleted file mode 100644 index 2f3e5b6e9..000000000 --- a/src/event_model/documents/partial_resource.py +++ /dev/null @@ -1,30 +0,0 @@ -# ruff: noqa -# generated by datamodel-codegen: -# filename: partial_resource.json - -from __future__ import annotations - -from typing import Any, Dict, TypedDict - - -class PartialResource(TypedDict): - resource_kwargs: Dict[str, Any] - """ - Additional argument to pass to the Handler to read a Resource - """ - resource_path: str - """ - Filepath or URI for locating this resource - """ - root: str - """ - Subset of resource_path that is a local detail, not semantic. - """ - spec: str - """ - String identifying the format/type of this Resource, used to identify a compatible Handler - """ - uid: str - """ - Globally unique identifier for this Resource - """ diff --git a/src/event_model/documents/resource.py b/src/event_model/documents/resource.py index 6790f8947..5fab61a33 100644 --- a/src/event_model/documents/resource.py +++ b/src/event_model/documents/resource.py @@ -9,16 +9,7 @@ from typing_extensions import NotRequired -class Resource(TypedDict): - """ - Document to reference a collection (e.g. file or group of files) of - externally-stored data - """ - - path_semantics: NotRequired[Literal["posix", "windows"]] - """ - Rules for joining paths - """ +class PartialResource(TypedDict): resource_kwargs: Dict[str, Any] """ Additional argument to pass to the Handler to read a Resource @@ -31,10 +22,6 @@ class Resource(TypedDict): """ Subset of resource_path that is a local detail, not semantic. """ - run_start: NotRequired[str] - """ - Globally unique ID to the run_start document this resource is associated with. - """ spec: str """ String identifying the format/type of this Resource, used to identify a compatible Handler @@ -43,3 +30,19 @@ class Resource(TypedDict): """ Globally unique identifier for this Resource """ + + +class Resource(PartialResource): + """ + Document to reference a collection (e.g. file or group of files) of + externally-stored data + """ + + path_semantics: NotRequired[Literal["posix", "windows"]] + """ + Rules for joining paths + """ + run_start: NotRequired[str] + """ + Globally unique ID to the run_start document this resource is associated with. + """ diff --git a/src/event_model/generate/create_documents.py b/src/event_model/generate/create_documents.py index a95f53572..0ff3bc7b3 100644 --- a/src/event_model/generate/create_documents.py +++ b/src/event_model/generate/create_documents.py @@ -14,6 +14,10 @@ TEMPLATES = Path(__file__).parent / "templates" +def snake_to_title(snake: str) -> str: + return snake.title().replace("_", "") + + # Used to add user written schema to autogenerated schema. def merge_dicts(dict1: dict, dict2: dict) -> dict: return_dict = dict2.copy() @@ -46,11 +50,13 @@ def sort_alphabetically(schema: Dict) -> Dict: "title": 0, "description": 1, "type": 2, - "$defs": 3, - "properties": 4, - "required": 5, - "patternProperties": 6, - "additionalProperties": 7, + "allOf": 3, + "$defs": 4, + "properties": 5, + "required": 6, + "patternProperties": 7, + "additionalProperties": 8, + "unevaluatedProperties": 9, } @@ -115,32 +121,65 @@ def get_jsonschema_path(jsonschema: Dict, root=JSONSCHEMA) -> Path: return root / f"{to_snake(jsonschema['title'])}.json" -def generate_jsonschema( +def generate_basemodel_schema( basemodel: Type[BaseModel], jsonschema_root=JSONSCHEMA, -) -> Path: - schema_extra: Dict[str, Any] = cast( - Dict[str, Any], basemodel.model_config.pop("json_schema_extra", {}) - ) - model_jsonschema = basemodel.model_json_schema() - - jsonschema_path = get_jsonschema_path(model_jsonschema, root=jsonschema_root) - - # Dump the schema with the extra schema, also updates extra schema - # if it's changed. - dump_json( - merge_dicts(model_jsonschema, schema_extra), - jsonschema_path=jsonschema_path, - ) + is_parent: bool = False, +) -> dict[str, Any]: + refs = [] for parent in [parent for parent in basemodel.__bases__ if parent is not BaseModel]: assert issubclass( parent, BaseModel ) # Parents of BaseModel's can only be other BaseModel - generate_jsonschema( + parent_jsonschema = generate_basemodel_schema( parent, jsonschema_root=jsonschema_root, + is_parent=True, ) + refs.append(parent_jsonschema) + + schema_extra: Dict[str, Any] = cast( + Dict[str, Any], basemodel.model_config.pop("json_schema_extra", {}) + ) + model_jsonschema = basemodel.model_json_schema() + model_jsonschema = merge_dicts(model_jsonschema, schema_extra) + + if is_parent or refs: + additional_properties = model_jsonschema.pop("additionalProperties", None) + if additional_properties is not None and not is_parent: + model_jsonschema["unevaluatedProperties"] = additional_properties + + if refs: + all_of_refs = [] + for ref in refs: + for property in ref["properties"]: + model_jsonschema["properties"].pop(property, None) + if model_jsonschema.get("$defs", None) is None: + model_jsonschema["$defs"] = {} + model_jsonschema["$defs"][snake_to_title(ref["title"])] = ref + all_of_refs.append({"$ref": f"#/$defs/{snake_to_title(ref['title'])}"}) + + if model_jsonschema.get("required", None) is not None: + for ref_property in ref["properties"]: + if ref_property in model_jsonschema["required"]: + model_jsonschema["required"].remove(ref_property) + + model_jsonschema["allOf"] = all_of_refs + + return model_jsonschema + + +def generate_jsonschema( + basemodel: Type[BaseModel], + jsonschema_root=JSONSCHEMA, +) -> Path: + model_jsonschema = generate_basemodel_schema( + basemodel, jsonschema_root=jsonschema_root + ) + jsonschema_path = get_jsonschema_path(model_jsonschema, root=jsonschema_root) + dump_json(model_jsonschema, jsonschema_path) + return jsonschema_path @@ -169,7 +208,7 @@ def generate_init_py(output_root: Path): ) document_class_names = [ - f"{document_name.title().replace('_', '')}" for document_name in document_names + f"{snake_to_title(document_name)}" for document_name in document_names ] init_py_imports = "\n".join( diff --git a/src/event_model/schemas/datum.json b/src/event_model/schemas/datum.json index 0aeb543f6..a85c6cf80 100644 --- a/src/event_model/schemas/datum.json +++ b/src/event_model/schemas/datum.json @@ -1,5 +1,5 @@ { - "title": "Datum", + "title": "datum", "description": "Document to reference a quanta of externally-stored data", "type": "object", "properties": { diff --git a/src/event_model/schemas/datum_page.json b/src/event_model/schemas/datum_page.json index a7f1259a9..768adb26f 100644 --- a/src/event_model/schemas/datum_page.json +++ b/src/event_model/schemas/datum_page.json @@ -1,5 +1,5 @@ { - "title": "DatumPage", + "title": "datum_page", "description": "Page of documents to reference a quanta of externally-stored data", "type": "object", "$defs": { diff --git a/src/event_model/schemas/event.json b/src/event_model/schemas/event.json index a47986631..213b89b4c 100644 --- a/src/event_model/schemas/event.json +++ b/src/event_model/schemas/event.json @@ -1,48 +1,66 @@ { - "title": "Event", + "title": "event", "description": "Document to record a quanta of collected data", "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PartialEvent" + } + ], + "$defs": { + "PartialEvent": { + "title": "partial_event", + "type": "object", + "properties": { + "data": { + "title": "Data", + "description": "The actual measurement data", + "type": "object" + }, + "filled": { + "title": "Filled", + "description": "Mapping each of the keys of externally-stored data to the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded)", + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + } + }, + "time": { + "title": "Time", + "description": "The event time. This maybe different than the timestamps on each of the data entries.", + "type": "number" + }, + "timestamps": { + "title": "Timestamps", + "description": "The timestamps of the individual measurement data", + "type": "object" + } + }, + "required": [ + "data", + "time", + "timestamps" + ] + } + }, "properties": { - "data": { - "title": "Data", - "description": "The actual measurement data", - "type": "object" - }, "descriptor": { "title": "Descriptor", "description": "UID of the EventDescriptor to which this Event belongs", "type": "string" }, - "filled": { - "title": "Filled", - "description": "Mapping each of the keys of externally-stored data to the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded)", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - } - }, "seq_num": { "title": "Seq Num", "description": "Sequence number to identify the location of this Event in the Event stream", "type": "integer" }, - "time": { - "title": "Time", - "description": "The event time. This maybe different than the timestamps on each of the data entries.", - "type": "number" - }, - "timestamps": { - "title": "Timestamps", - "description": "The timestamps of the individual measurement data", - "type": "object" - }, "uid": { "title": "Uid", "description": "Globally unique identifier for this Event", @@ -50,12 +68,9 @@ } }, "required": [ - "data", "descriptor", "seq_num", - "time", - "timestamps", "uid" ], - "additionalProperties": false + "unevaluatedProperties": false } diff --git a/src/event_model/schemas/event_descriptor.json b/src/event_model/schemas/event_descriptor.json index c30562d76..62cb3cd98 100644 --- a/src/event_model/schemas/event_descriptor.json +++ b/src/event_model/schemas/event_descriptor.json @@ -1,5 +1,5 @@ { - "title": "EventDescriptor", + "title": "event_descriptor", "description": "Document to describe the data captured in the associated event\ndocuments", "type": "object", "$defs": { diff --git a/src/event_model/schemas/event_page.json b/src/event_model/schemas/event_page.json index c52683bd3..862670d8c 100644 --- a/src/event_model/schemas/event_page.json +++ b/src/event_model/schemas/event_page.json @@ -1,41 +1,76 @@ { - "title": "EventPage", + "title": "event_page", "description": "Page of documents to record a quanta of collected data", "type": "object", - "properties": { - "data": { - "title": "Data", - "description": "The actual measurement data", + "allOf": [ + { + "$ref": "#/$defs/PartialEventPage" + } + ], + "$defs": { + "PartialEventPage": { + "title": "partial_event_page", "type": "object", - "additionalProperties": { - "items": {}, - "type": "array" - } - }, + "properties": { + "data": { + "title": "Data", + "description": "The actual measurement data", + "type": "object", + "additionalProperties": { + "items": {}, + "type": "array" + } + }, + "filled": { + "title": "Filled", + "description": "Mapping each of the keys of externally-stored data to an array containing the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded)", + "type": "object", + "additionalProperties": { + "items": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + }, + "type": "array" + }, + "default": {} + }, + "time": { + "title": "Time", + "description": "Array of Event times. This maybe different than the timestamps on each of the data entries", + "type": "array", + "items": { + "type": "number" + } + }, + "timestamps": { + "title": "Timestamps", + "description": "The timestamps of the individual measurement data", + "type": "object", + "additionalProperties": { + "items": {}, + "type": "array" + } + } + }, + "required": [ + "data", + "time", + "timestamps" + ] + } + }, + "properties": { "descriptor": { "title": "Descriptor", "description": "The UID of the EventDescriptor to which all of the Events in this page belong", "type": "string" }, - "filled": { - "title": "Filled", - "description": "Mapping each of the keys of externally-stored data to an array containing the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded)", - "type": "object", - "additionalProperties": { - "items": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "type": "array" - }, - "default": {} - }, "seq_num": { "title": "Seq Num", "description": "Array of sequence numbers to identify the location of each Event in the Event stream", @@ -44,23 +79,6 @@ "type": "integer" } }, - "time": { - "title": "Time", - "description": "Array of Event times. This maybe different than the timestamps on each of the data entries", - "type": "array", - "items": { - "type": "number" - } - }, - "timestamps": { - "title": "Timestamps", - "description": "The timestamps of the individual measurement data", - "type": "object", - "additionalProperties": { - "items": {}, - "type": "array" - } - }, "uid": { "title": "Uid", "description": "Array of globally unique identifiers for each Event", @@ -71,12 +89,9 @@ } }, "required": [ - "data", "descriptor", "seq_num", - "time", - "timestamps", "uid" ], - "additionalProperties": false + "unevaluatedProperties": false } diff --git a/src/event_model/schemas/partial_event.json b/src/event_model/schemas/partial_event.json deleted file mode 100644 index 74ce96efc..000000000 --- a/src/event_model/schemas/partial_event.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "title": "PartialEvent", - "type": "object", - "properties": { - "data": { - "title": "Data", - "description": "The actual measurement data", - "type": "object" - }, - "filled": { - "title": "Filled", - "description": "Mapping each of the keys of externally-stored data to the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded)", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - } - }, - "time": { - "title": "Time", - "description": "The event time. This maybe different than the timestamps on each of the data entries.", - "type": "number" - }, - "timestamps": { - "title": "Timestamps", - "description": "The timestamps of the individual measurement data", - "type": "object" - } - }, - "required": [ - "data", - "time", - "timestamps" - ], - "additionalProperties": false -} diff --git a/src/event_model/schemas/partial_event_page.json b/src/event_model/schemas/partial_event_page.json deleted file mode 100644 index c7d054227..000000000 --- a/src/event_model/schemas/partial_event_page.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "title": "PartialEventPage", - "type": "object", - "properties": { - "data": { - "title": "Data", - "description": "The actual measurement data", - "type": "object", - "additionalProperties": { - "items": {}, - "type": "array" - } - }, - "filled": { - "title": "Filled", - "description": "Mapping each of the keys of externally-stored data to an array containing the boolean False, indicating that the data has not been loaded, or to foreign keys (moved here from 'data' when the data was loaded)", - "type": "object", - "additionalProperties": { - "items": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ] - }, - "type": "array" - }, - "default": {} - }, - "time": { - "title": "Time", - "description": "Array of Event times. This maybe different than the timestamps on each of the data entries", - "type": "array", - "items": { - "type": "number" - } - }, - "timestamps": { - "title": "Timestamps", - "description": "The timestamps of the individual measurement data", - "type": "object", - "additionalProperties": { - "items": {}, - "type": "array" - } - } - }, - "required": [ - "data", - "time", - "timestamps" - ], - "additionalProperties": false -} diff --git a/src/event_model/schemas/partial_resource.json b/src/event_model/schemas/partial_resource.json deleted file mode 100644 index 47430cbec..000000000 --- a/src/event_model/schemas/partial_resource.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "title": "PartialResource", - "type": "object", - "properties": { - "resource_kwargs": { - "title": "Resource Kwargs", - "description": "Additional argument to pass to the Handler to read a Resource", - "type": "object" - }, - "resource_path": { - "title": "Resource Path", - "description": "Filepath or URI for locating this resource", - "type": "string" - }, - "root": { - "title": "Root", - "description": "Subset of resource_path that is a local detail, not semantic.", - "type": "string" - }, - "spec": { - "title": "Spec", - "description": "String identifying the format/type of this Resource, used to identify a compatible Handler", - "type": "string" - }, - "uid": { - "title": "Uid", - "description": "Globally unique identifier for this Resource", - "type": "string" - } - }, - "required": [ - "resource_kwargs", - "resource_path", - "root", - "spec", - "uid" - ], - "additionalProperties": false -} diff --git a/src/event_model/schemas/resource.json b/src/event_model/schemas/resource.json index 796985632..434b74aac 100644 --- a/src/event_model/schemas/resource.json +++ b/src/event_model/schemas/resource.json @@ -1,7 +1,52 @@ { - "title": "Resource", + "title": "resource", "description": "Document to reference a collection (e.g. file or group of files) of\nexternally-stored data", "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PartialResource" + } + ], + "$defs": { + "PartialResource": { + "title": "partial_resource", + "type": "object", + "properties": { + "resource_kwargs": { + "title": "Resource Kwargs", + "description": "Additional argument to pass to the Handler to read a Resource", + "type": "object" + }, + "resource_path": { + "title": "Resource Path", + "description": "Filepath or URI for locating this resource", + "type": "string" + }, + "root": { + "title": "Root", + "description": "Subset of resource_path that is a local detail, not semantic.", + "type": "string" + }, + "spec": { + "title": "Spec", + "description": "String identifying the format/type of this Resource, used to identify a compatible Handler", + "type": "string" + }, + "uid": { + "title": "Uid", + "description": "Globally unique identifier for this Resource", + "type": "string" + } + }, + "required": [ + "resource_kwargs", + "resource_path", + "root", + "spec", + "uid" + ] + } + }, "properties": { "path_semantics": { "title": "Path Semantics", @@ -13,44 +58,13 @@ "windows" ] }, - "resource_kwargs": { - "title": "Resource Kwargs", - "description": "Additional argument to pass to the Handler to read a Resource", - "type": "object" - }, - "resource_path": { - "title": "Resource Path", - "description": "Filepath or URI for locating this resource", - "type": "string" - }, - "root": { - "title": "Root", - "description": "Subset of resource_path that is a local detail, not semantic.", - "type": "string" - }, "run_start": { "title": "Run Start", "description": "Globally unique ID to the run_start document this resource is associated with.", "type": "string", "default": "" - }, - "spec": { - "title": "Spec", - "description": "String identifying the format/type of this Resource, used to identify a compatible Handler", - "type": "string" - }, - "uid": { - "title": "Uid", - "description": "Globally unique identifier for this Resource", - "type": "string" } }, - "required": [ - "resource_kwargs", - "resource_path", - "root", - "spec", - "uid" - ], - "additionalProperties": false + "required": [], + "unevaluatedProperties": false } diff --git a/src/event_model/schemas/run_start.json b/src/event_model/schemas/run_start.json index d9952733d..415b8df00 100644 --- a/src/event_model/schemas/run_start.json +++ b/src/event_model/schemas/run_start.json @@ -1,5 +1,5 @@ { - "title": "RunStart", + "title": "run_start", "description": "Document created at the start of run. Provides a seach target and\nlater documents link to it", "type": "object", "$defs": { diff --git a/src/event_model/schemas/run_stop.json b/src/event_model/schemas/run_stop.json index c2ba9e226..bb91d4de0 100644 --- a/src/event_model/schemas/run_stop.json +++ b/src/event_model/schemas/run_stop.json @@ -1,5 +1,5 @@ { - "title": "RunStop", + "title": "run_stop", "description": "Document for the end of a run indicating the success/fail state of the\nrun and the end time", "type": "object", "$defs": { diff --git a/src/event_model/schemas/stream_datum.json b/src/event_model/schemas/stream_datum.json index 7b47d0930..c6c479140 100644 --- a/src/event_model/schemas/stream_datum.json +++ b/src/event_model/schemas/stream_datum.json @@ -1,5 +1,5 @@ { - "title": "StreamDatum", + "title": "stream_datum", "description": "Document to reference a quanta of an externally-stored stream of data.", "type": "object", "$defs": { @@ -56,5 +56,6 @@ "seq_nums", "stream_resource", "uid" - ] + ], + "additionalProperties": true } diff --git a/src/event_model/schemas/stream_resource.json b/src/event_model/schemas/stream_resource.json index b2b29e698..4e74d379b 100644 --- a/src/event_model/schemas/stream_resource.json +++ b/src/event_model/schemas/stream_resource.json @@ -1,5 +1,5 @@ { - "title": "StreamResource", + "title": "stream_resource", "description": "Document to reference a collection (e.g. file or group of files) of\nexternally-stored data streams", "type": "object", "properties": { @@ -41,5 +41,6 @@ "parameters", "uid", "uri" - ] + ], + "additionalProperties": true }