Skip to content

Commit

Permalink
General adjustments to work with ophyd-async and bluesky
Browse files Browse the repository at this point in the history
  • Loading branch information
evalott100 committed Jan 13, 2025
1 parent 4598584 commit a683dc5
Show file tree
Hide file tree
Showing 23 changed files with 199 additions and 166 deletions.
3 changes: 2 additions & 1 deletion src/event_model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from .documents.event_descriptor import (
Configuration,
DataKey,
Dtype,
EventDescriptor,
Limits,
LimitsRange,
Expand Down Expand Up @@ -75,6 +76,7 @@
"PartialEvent",
"Configuration",
"DataKey",
"Dtype",
"EventDescriptor",
"Limits",
"LimitsRange",
Expand All @@ -89,7 +91,6 @@
"StaticProjection",
"CalculatedEventProjection",
"ConfigurationProjection",
"Projection",
"Projections",
"RunStart",
"RunStop",
Expand Down
2 changes: 1 addition & 1 deletion src/event_model/basemodels/datum.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class Datum(BaseModel):
"""Document to reference a quanta of externally-stored data"""

model_config = ConfigDict(title="datum", extra="forbid")
model_config = ConfigDict(extra="forbid")

datum_id: Annotated[
str,
Expand Down
2 changes: 1 addition & 1 deletion src/event_model/basemodels/datum_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class DataFrameForDatumPage(RootModel):
class DatumPage(BaseModel):
"""Page of documents to reference a quanta of externally-stored data"""

model_config = ConfigDict(title="datum_page", extra="forbid")
model_config = ConfigDict(extra="forbid")

datum_id: Annotated[
DataFrameForDatumPage,
Expand Down
4 changes: 2 additions & 2 deletions src/event_model/basemodels/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class PartialEvent(BaseModel):
model_config = ConfigDict(title="partial_event", extra="forbid")
model_config = ConfigDict(extra="forbid")

data: Annotated[Dict[str, Any], Field(description="The actual measurement data")]
filled: Annotated[
Expand Down Expand Up @@ -33,7 +33,7 @@ class PartialEvent(BaseModel):
class Event(PartialEvent):
"""Document to record a quanta of collected data"""

model_config = ConfigDict(title="event", extra="forbid")
model_config = ConfigDict(extra="forbid")

descriptor: Annotated[
str, Field(description="UID of the EventDescriptor to which this Event belongs")
Expand Down
11 changes: 6 additions & 5 deletions src/event_model/basemodels/event_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
from pydantic.config import JsonDict
from typing_extensions import Annotated, Literal

Dtype = Literal["string", "number", "array", "boolean", "integer"]

class Dtype(RootModel):
root: Literal["string", "number", "array", "boolean", "integer"]


NO_DOTS_PATTERN = r"^([^./]+)$"
Expand Down Expand Up @@ -112,7 +114,7 @@ class Limits(BaseModel):
class DataKey(BaseModel):
"""Describes the objects in the data property of Event documents"""

model_config = ConfigDict(extra="forbid")
model_config = ConfigDict(extra="allow")

limits: Annotated[
Limits,
Expand Down Expand Up @@ -199,7 +201,7 @@ class DataKey(BaseModel):
class PerObjectHint(BaseModel):
"""The 'interesting' data keys for this device."""

model_config = ConfigDict(extra="forbid")
model_config = ConfigDict(extra="allow")

fields: Annotated[
List[str],
Expand All @@ -216,7 +218,7 @@ class PerObjectHint(BaseModel):


class Configuration(BaseModel):
model_config = ConfigDict(extra="forbid")
model_config = ConfigDict(extra="allow")
data: Annotated[
Dict[str, Any],
Field(default={}, description="The actual measurement data"),
Expand Down Expand Up @@ -256,7 +258,6 @@ class EventDescriptor(BaseModel):
documents"""

model_config = ConfigDict(
title="event_descriptor",
extra="allow",
json_schema_extra=EVENT_DESCRIPTOR_EXTRA_SCHEMA,
)
Expand Down
4 changes: 2 additions & 2 deletions src/event_model/basemodels/event_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


class PartialEventPage(BaseModel):
model_config = ConfigDict(title="partial_event_page", extra="forbid")
model_config = ConfigDict(extra="forbid")

data: Annotated[
DataFrameForEventPage,
Expand Down Expand Up @@ -44,7 +44,7 @@ class PartialEventPage(BaseModel):
class EventPage(PartialEventPage):
"""Page of documents to record a quanta of collected data"""

model_config = ConfigDict(title="event_page", extra="forbid")
model_config = ConfigDict(extra="forbid")

descriptor: Annotated[
str,
Expand Down
4 changes: 2 additions & 2 deletions src/event_model/basemodels/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class PartialResource(BaseModel):
model_config = ConfigDict(title="partial_resource", extra="forbid")
model_config = ConfigDict(extra="forbid")

spec: Annotated[
str,
Expand Down Expand Up @@ -41,7 +41,7 @@ class Resource(PartialResource):
externally-stored data
"""

model_config = ConfigDict(title="resource", extra="forbid")
model_config = ConfigDict(extra="forbid")

path_semantics: Annotated[
Literal["posix", "windows"],
Expand Down
8 changes: 3 additions & 5 deletions src/event_model/basemodels/run_start.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def validate_root(cls, value):
class Hints(BaseModel):
"""Start-level hints"""

model_config = ConfigDict(extra="forbid")
model_config = ConfigDict(extra="allow")

dimensions: Annotated[
List[List[Union[List[str], str]]],
Expand All @@ -48,7 +48,7 @@ class Hints(BaseModel):


class Calculation(BaseModel):
model_config = ConfigDict(extra="forbid")
model_config = ConfigDict(extra="allow")

args: Annotated[List, Field(default=[])]
callable: Annotated[
Expand Down Expand Up @@ -192,9 +192,7 @@ class RunStart(BaseModel):
later documents link to it
"""

model_config = ConfigDict(
title="run_start", extra="allow", json_schema_extra=RUN_START_EXTRA_SCHEMA
)
model_config = ConfigDict(extra="allow", json_schema_extra=RUN_START_EXTRA_SCHEMA)

data_groups: Annotated[
List[str],
Expand Down
1 change: 0 additions & 1 deletion src/event_model/basemodels/run_stop.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class RunStop(BaseModel):
"""

model_config = ConfigDict(
title="run_stop",
extra="allow",
json_schema_extra=RUN_STOP_EXTRA_SCHEMA,
)
Expand Down
1 change: 0 additions & 1 deletion src/event_model/basemodels/stream_datum.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class StreamDatum(BaseModel):
"""Document to reference a quanta of an externally-stored stream of data."""

model_config = ConfigDict(
title="stream_datum",
extra="allow",
)

Expand Down
1 change: 0 additions & 1 deletion src/event_model/basemodels/stream_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class StreamResource(BaseModel):
"""

model_config = ConfigDict(
title="stream_resource",
extra="allow",
)

Expand Down
5 changes: 4 additions & 1 deletion src/event_model/documents/event_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
DataType = Any


Dtype = Literal["string", "number", "array", "boolean", "integer"]


class LimitsRange(TypedDict):
high: Optional[float]
low: Optional[float]
Expand Down Expand Up @@ -100,7 +103,7 @@ class DataKey(TypedDict):
"""
The names for dimensions of the data. Null or empty list if scalar data
"""
dtype: Literal["string", "number", "array", "boolean", "integer"]
dtype: Dtype
"""
The type of the data in the event, given as a broad JSON schema type.
"""
Expand Down
36 changes: 26 additions & 10 deletions src/event_model/generate/create_documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import datamodel_code_generator
from pydantic import BaseModel
from pydantic.alias_generators import to_snake
from pydantic.json_schema import GenerateJsonSchema

from event_model.basemodels import ALL_BASEMODELS

Expand All @@ -14,6 +15,20 @@
TEMPLATES = Path(__file__).parent / "templates"


class SnakeCaseTitleField(GenerateJsonSchema):
def generate(self, schema, mode="validation"):
jsonschema = super().generate(schema, mode=mode)
jsonschema["title"] = to_snake(jsonschema["title"])

for key, property in jsonschema.get("properties", {}).items():
property["title"] = to_snake(key)
for definition in jsonschema.get("$defs", {}).values():
definition["title"] = to_snake(definition["title"])
for key, property in definition.get("properties", {}).items():
property["title"] = to_snake(key)
return jsonschema


def snake_to_title(snake: str) -> str:
return snake.title().replace("_", "")

Expand Down Expand Up @@ -121,7 +136,7 @@ def get_jsonschema_path(jsonschema: Dict, root=JSONSCHEMA) -> Path:
return root / f"{to_snake(jsonschema['title'])}.json"


def generate_basemodel_schema(
def _generate_jsonschema(
basemodel: Type[BaseModel],
jsonschema_root=JSONSCHEMA,
is_parent: bool = False,
Expand All @@ -132,7 +147,7 @@ def generate_basemodel_schema(
assert issubclass(
parent, BaseModel
) # Parents of BaseModel's can only be other BaseModel
parent_jsonschema = generate_basemodel_schema(
parent_jsonschema = _generate_jsonschema(
parent,
jsonschema_root=jsonschema_root,
is_parent=True,
Expand All @@ -142,15 +157,18 @@ def generate_basemodel_schema(
schema_extra: Dict[str, Any] = cast(
Dict[str, Any], basemodel.model_config.pop("json_schema_extra", {})
)
model_jsonschema = basemodel.model_json_schema()
model_jsonschema = basemodel.model_json_schema(schema_generator=SnakeCaseTitleField)
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
additional_properties = (
model_jsonschema.pop("additionalProperties", None)
if is_parent or refs
else None
)

if refs:
if additional_properties is not None and not is_parent:
model_jsonschema["unevaluatedProperties"] = additional_properties
all_of_refs = []
for ref in refs:
for property in ref["properties"]:
Expand All @@ -174,9 +192,7 @@ def generate_jsonschema(
basemodel: Type[BaseModel],
jsonschema_root=JSONSCHEMA,
) -> Path:
model_jsonschema = generate_basemodel_schema(
basemodel, jsonschema_root=jsonschema_root
)
model_jsonschema = _generate_jsonschema(basemodel, jsonschema_root=jsonschema_root)
jsonschema_path = get_jsonschema_path(model_jsonschema, root=jsonschema_root)
dump_json(model_jsonschema, jsonschema_path)

Expand Down
6 changes: 3 additions & 3 deletions src/event_model/schemas/datum.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
"type": "object",
"properties": {
"datum_id": {
"title": "Datum Id",
"title": "datum_id",
"description": "Globally unique identifier for this Datum (akin to 'uid' for other Document types), typically formatted as '<resource>/<integer>'",
"type": "string"
},
"datum_kwargs": {
"title": "Datum Kwargs",
"title": "datum_kwargs",
"description": "Arguments to pass to the Handler to retrieve one quanta of data",
"type": "object"
},
"resource": {
"title": "Resource",
"title": "resource",
"description": "The UID of the Resource to which this Datum belongs",
"type": "string"
}
Expand Down
7 changes: 4 additions & 3 deletions src/event_model/schemas/datum_page.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "object",
"$defs": {
"DataFrameForDatumPage": {
"title": "DataFrameForDatumPage",
"title": "data_frame_for_datum_page",
"type": "array",
"items": {
"type": "string"
Expand All @@ -13,11 +13,12 @@
},
"properties": {
"datum_id": {
"title": "datum_id",
"description": "Array unique identifiers for each Datum (akin to 'uid' for other Document types), typically formatted as '<resource>/<integer>'",
"$ref": "#/$defs/DataFrameForDatumPage"
},
"datum_kwargs": {
"title": "Datum Kwargs",
"title": "datum_kwargs",
"description": "Array of arguments to pass to the Handler to retrieve one quanta of data",
"type": "object",
"additionalProperties": {
Expand All @@ -26,7 +27,7 @@
}
},
"resource": {
"title": "Resource",
"title": "resource",
"description": "The UID of the Resource to which all Datums in the page belong",
"type": "string"
}
Expand Down
14 changes: 7 additions & 7 deletions src/event_model/schemas/event.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
"type": "object",
"properties": {
"data": {
"title": "Data",
"title": "data",
"description": "The actual measurement data",
"type": "object"
},
"filled": {
"title": "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": {
Expand All @@ -33,12 +33,12 @@
}
},
"time": {
"title": "Time",
"title": "time",
"description": "The event time. This maybe different than the timestamps on each of the data entries.",
"type": "number"
},
"timestamps": {
"title": "Timestamps",
"title": "timestamps",
"description": "The timestamps of the individual measurement data",
"type": "object"
}
Expand All @@ -52,17 +52,17 @@
},
"properties": {
"descriptor": {
"title": "Descriptor",
"title": "descriptor",
"description": "UID of the EventDescriptor to which this Event belongs",
"type": "string"
},
"seq_num": {
"title": "Seq Num",
"title": "seq_num",
"description": "Sequence number to identify the location of this Event in the Event stream",
"type": "integer"
},
"uid": {
"title": "Uid",
"title": "uid",
"description": "Globally unique identifier for this Event",
"type": "string"
}
Expand Down
Loading

0 comments on commit a683dc5

Please sign in to comment.