Skip to content
Draft
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
33 changes: 31 additions & 2 deletions src/blueapi/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from bluesky_stomp.models import Broker
from click.exceptions import ClickException
from observability_utils.tracing import setup_tracing
from pydantic import ValidationError
from pydantic import HttpUrl, ValidationError
from requests.exceptions import ConnectionError

from blueapi import __version__, config
Expand All @@ -32,6 +32,7 @@
from blueapi.config import (
ApplicationConfig,
ConfigLoader,
StompConfig,
)
from blueapi.core import OTLP_EXPORT_ENABLED, DataEvent
from blueapi.log import set_up_logging
Expand Down Expand Up @@ -159,8 +160,18 @@ def start_application(obj: dict):
type=click.Choice([o.name.lower() for o in OutputFormat]),
default="compact",
)
@click.option(
"--url",
type=str,
help="URL for the blueapi server to connect to.",
default=None,
)
@click.pass_context
def controller(ctx: click.Context, output: str) -> None:
def controller(
ctx: click.Context,
output: str,
url: str | None,
) -> None:
"""Client utility for controlling and introspecting the worker"""

setup_tracing("BlueAPICLI", OTLP_EXPORT_ENABLED)
Expand All @@ -170,9 +181,18 @@ def controller(ctx: click.Context, output: str) -> None:

ctx.ensure_object(dict)
config: ApplicationConfig = ctx.obj["config"]

if url is not None:
config.api.url = HttpUrl(url)

ctx.obj["fmt"] = OutputFormat(output)
ctx.obj["client"] = BlueapiClient.from_config(config)

client: BlueapiClient = ctx.obj["client"]
stomp_config: StompConfig = client.get_stomp_config()
config.stomp = stomp_config
ctx.obj["client"] = BlueapiClient.from_config(config)


P = ParamSpec("P")
T = TypeVar("T")
Expand All @@ -198,6 +218,15 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
return wrapper


@controller.command(name="stomp")
@click.pass_obj
@check_connection
def get_stomp_config(obj: dict) -> None:
"""Get the stomp config the server is using"""
client: BlueapiClient = obj["client"]
obj["fmt"].display(client.get_stomp_config())


@controller.command(name="plans")
@click.pass_obj
@check_connection
Expand Down
3 changes: 3 additions & 0 deletions src/blueapi/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ def from_config(cls, config: ApplicationConfig) -> "BlueapiClient":
else:
return cls(rest)

def get_stomp_config(self):
return self._rest.get_stomp_config()

@start_as_current_span(TRACER)
def get_plans(self) -> PlanResponse:
"""
Expand Down
5 changes: 4 additions & 1 deletion src/blueapi/client/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)
from pydantic import BaseModel, TypeAdapter, ValidationError

from blueapi.config import RestConfig
from blueapi.config import RestConfig, StompConfig
from blueapi.service.authentication import JWTAuth, SessionManager
from blueapi.service.model import (
DeviceModel,
Expand Down Expand Up @@ -215,6 +215,9 @@ def cancel_current_task(
data={"new_state": state, "reason": reason},
)

def get_stomp_config(self):
return self._request_and_deserialize("/config/stomp", StompConfig)

def get_environment(self) -> EnvironmentResponse:
return self._request_and_deserialize("/environment", EnvironmentResponse)

Expand Down
4 changes: 4 additions & 0 deletions src/blueapi/service/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ def get_oidc_config() -> OIDCConfig | None:
return config().oidc


def get_stomp_config() -> StompConfig | None:
return config().stomp


def get_python_env(
name: str | None = None, source: SourceInfo | None = None
) -> PythonEnvironmentResponse:
Expand Down
18 changes: 17 additions & 1 deletion src/blueapi/service/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from starlette.responses import JSONResponse
from super_state_machine.errors import TransitionError

from blueapi.config import ApplicationConfig, OIDCConfig
from blueapi.config import ApplicationConfig, OIDCConfig, StompConfig
from blueapi.service import interface
from blueapi.worker import TrackableTask, WorkerState
from blueapi.worker.event import TaskStatusEnum
Expand Down Expand Up @@ -244,6 +244,22 @@ def get_oidc_config(
return config


@open_router.get(
"/config/stomp",
tags=[Tag.META],
responses={status.HTTP_204_NO_CONTENT: {"description": "No Stomp configured"}},
)
@start_as_current_span(TRACER)
def get_stomp_config(
runner: Annotated[WorkerDispatcher, Depends(_runner)],
) -> StompConfig:
"""Retrieve the stomp configuration for the server."""
config = runner.run(interface.get_stomp_config)
if config is None:
raise HTTPException(status_code=status.HTTP_204_NO_CONTENT)
return config


@secure_router.get("/plans", tags=[Tag.PLAN])
@start_as_current_span(TRACER)
def get_plans(runner: Annotated[WorkerDispatcher, Depends(_runner)]) -> PlanResponse:
Expand Down
Loading