Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 92 additions & 40 deletions helm/blueapi/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,89 @@
"title": "CORSConfig",
"type": "object"
},
"DeviceSource": {
"additionalProperties": false,
"properties": {
"module": {
"description": "Module to be imported",
"title": "Module",
"type": "string"
},
"kind": {
"const": "deviceFunctions",
"default": "deviceFunctions",
"title": "Kind",
"type": "string"
}
},
"required": [
"module"
],
"title": "DeviceSource",
"type": "object"
},
"DodalSource": {
"additionalProperties": false,
"properties": {
"module": {
"description": "Module to be imported",
"title": "Module",
"type": "string"
},
"kind": {
"const": "dodal",
"default": "dodal",
"title": "Kind",
"type": "string"
},
"mock": {
"default": false,
"description": "If true, ophyd_async device connections are mocked",
"title": "Mock",
"type": "boolean"
}
},
"required": [
"module"
],
"title": "DodalSource",
"type": "object"
},
"EnvironmentConfig": {
"additionalProperties": false,
"description": "Config for the RunEngine environment",
"properties": {
"sources": {
"default": [
{
"kind": "planFunctions",
"module": "dodal.plans"
"module": "dodal.plans",
"kind": "planFunctions"
},
{
"kind": "planFunctions",
"module": "dodal.plan_stubs.wrapped"
"module": "dodal.plan_stubs.wrapped",
"kind": "planFunctions"
}
],
"items": {
"$ref": "#/$defs/Source"
"discriminator": {
"mapping": {
"deviceFunctions": "#/$defs/DeviceSource",
"dodal": "#/$defs/DodalSource",
"planFunctions": "#/$defs/PlanSource"
},
"propertyName": "kind"
},
"oneOf": [
{
"$ref": "#/$defs/PlanSource"
},
{
"$ref": "#/$defs/DeviceSource"
},
{
"$ref": "#/$defs/DodalSource"
}
]
},
"title": "Sources",
"type": "array"
Expand Down Expand Up @@ -216,6 +282,27 @@
"title": "OIDCConfig",
"type": "object"
},
"PlanSource": {
"additionalProperties": false,
"properties": {
"module": {
"description": "Module to be imported",
"title": "Module",
"type": "string"
},
"kind": {
"const": "planFunctions",
"default": "planFunctions",
"title": "Kind",
"type": "string"
}
},
"required": [
"module"
],
"title": "PlanSource",
"type": "object"
},
"RestConfig": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -296,41 +383,6 @@
"title": "ScratchRepository",
"type": "object"
},
"Source": {
"additionalProperties": false,
"properties": {
"kind": {
"$ref": "#/$defs/SourceKind"
},
"module": {
"anyOf": [
{
"format": "path",
"type": "string"
},
{
"type": "string"
}
],
"title": "Module"
}
},
"required": [
"kind",
"module"
],
"title": "Source",
"type": "object"
},
"SourceKind": {
"enum": [
"planFunctions",
"deviceFunctions",
"dodal"
],
"title": "SourceKind",
"type": "string"
},
"StompConfig": {
"additionalProperties": false,
"description": "Config for connecting to stomp broker",
Expand Down
112 changes: 77 additions & 35 deletions helm/blueapi/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,52 @@
},
"additionalProperties": false
},
"DeviceSource": {
"title": "DeviceSource",
"type": "object",
"required": [
"module"
],
"properties": {
"kind": {
"title": "Kind",
"default": "deviceFunctions",
"const": "deviceFunctions"
},
"module": {
"title": "Module",
"description": "Module to be imported",
"type": "string"
}
},
"additionalProperties": false
},
"DodalSource": {
"title": "DodalSource",
"type": "object",
"required": [
"module"
],
"properties": {
"kind": {
"title": "Kind",
"default": "dodal",
"const": "dodal"
},
"mock": {
"title": "Mock",
"description": "If true, ophyd_async device connections are mocked",
"default": false,
"type": "boolean"
},
"module": {
"title": "Module",
"description": "Module to be imported",
"type": "string"
}
},
"additionalProperties": false
},
"EnvironmentConfig": {
"title": "EnvironmentConfig",
"description": "Config for the RunEngine environment",
Expand Down Expand Up @@ -585,7 +631,17 @@
],
"type": "array",
"items": {
"$ref": "#/$defs/Source"
"oneOf": [
{
"$ref": "#/$defs/PlanSource"
},
{
"$ref": "#/$defs/DeviceSource"
},
{
"$ref": "#/$defs/DodalSource"
}
]
}
}
},
Expand Down Expand Up @@ -702,6 +758,26 @@
},
"additionalProperties": false
},
"PlanSource": {
"title": "PlanSource",
"type": "object",
"required": [
"module"
],
"properties": {
"kind": {
"title": "Kind",
"default": "planFunctions",
"const": "planFunctions"
},
"module": {
"title": "Module",
"description": "Module to be imported",
"type": "string"
}
},
"additionalProperties": false
},
"RestConfig": {
"title": "RestConfig",
"type": "object",
Expand Down Expand Up @@ -778,40 +854,6 @@
},
"additionalProperties": false
},
"Source": {
"title": "Source",
"type": "object",
"required": [
"kind",
"module"
],
"properties": {
"kind": {
"$ref": "#/$defs/SourceKind"
},
"module": {
"title": "Module",
"anyOf": [
{
"type": "string"
},
{
"type": "string"
}
]
}
},
"additionalProperties": false
},
"SourceKind": {
"title": "SourceKind",
"type": "string",
"enum": [
"planFunctions",
"deviceFunctions",
"dodal"
]
},
"StompConfig": {
"title": "StompConfig",
"description": "Config for connecting to stomp broker",
Expand Down
35 changes: 29 additions & 6 deletions src/blueapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from functools import cached_property
from pathlib import Path
from string import Template
from typing import Any, Generic, Literal, TypeVar, cast
from typing import Annotated, Any, Generic, Literal, TypeVar, cast

import requests
import yaml
Expand Down Expand Up @@ -50,8 +50,26 @@ class SourceKind(str, Enum):


class Source(BlueapiBaseModel):
kind: SourceKind
module: Path | str
module: str = Field(description="Module to be imported")


class PlanSource(Source):
kind: Literal[SourceKind.PLAN_FUNCTIONS] = Field(
SourceKind.PLAN_FUNCTIONS, init=False
)


class DeviceSource(Source):
kind: Literal[SourceKind.DEVICE_FUNCTIONS] = Field(
SourceKind.DEVICE_FUNCTIONS, init=False
)


class DodalSource(Source):
kind: Literal[SourceKind.DODAL] = Field(SourceKind.DODAL, init=False)
mock: bool = Field(
description="If true, ophyd_async device connections are mocked", default=False
)


class TcpUrl(AnyUrl):
Expand Down Expand Up @@ -101,9 +119,14 @@ class EnvironmentConfig(BlueapiBaseModel):
Config for the RunEngine environment
"""

sources: list[Source] = [
Source(kind=SourceKind.PLAN_FUNCTIONS, module="dodal.plans"),
Source(kind=SourceKind.PLAN_FUNCTIONS, module="dodal.plan_stubs.wrapped"),
sources: list[
Annotated[
PlanSource | DeviceSource | DodalSource,
Field(discriminator="kind"),
]
] = [
PlanSource(module="dodal.plans"),
PlanSource(module="dodal.plan_stubs.wrapped"),
]
events: WorkerEventConfig = Field(default_factory=WorkerEventConfig)
metadata: MetadataConfig | None = Field(default=None)
Expand Down
25 changes: 16 additions & 9 deletions src/blueapi/core/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@

from blueapi import utils
from blueapi.client.numtracker import NumtrackerClient
from blueapi.config import ApplicationConfig, EnvironmentConfig, SourceKind
from blueapi.config import (
ApplicationConfig,
DeviceSource,
DodalSource,
EnvironmentConfig,
PlanSource,
)
from blueapi.utils import (
BlueapiPlanModelConfig,
is_function_sourced_from_module,
Expand Down Expand Up @@ -179,14 +185,15 @@ def with_config(self, config: EnvironmentConfig) -> None:
if config.metadata is not None:
self.run_engine.md |= config.metadata.model_dump()
for source in config.sources:
mod = import_module(str(source.module))

if source.kind is SourceKind.PLAN_FUNCTIONS:
self.with_plan_module(mod)
elif source.kind is SourceKind.DEVICE_FUNCTIONS:
self.with_device_module(mod)
elif source.kind is SourceKind.DODAL:
self.with_dodal_module(mod)
mod = import_module(source.module)

match source:
case PlanSource():
self.with_plan_module(mod)
case DeviceSource():
self.with_device_module(mod)
case DodalSource(mock=mock):
self.with_dodal_module(mod, mock=mock)

def with_plan_module(self, module: ModuleType) -> None:
"""
Expand Down
Loading