Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make all API models convert to camelCase #132

Merged
merged 4 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
12 changes: 7 additions & 5 deletions src/blueapi/config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from pathlib import Path
from typing import Union

from pydantic import BaseModel, Field
from pydantic import Field

from blueapi.utils import BlueapiBaseModel

class StompConfig(BaseModel):

class StompConfig(BlueapiBaseModel):
"""
Config for connecting to stomp broker
"""
Expand All @@ -13,19 +15,19 @@ class StompConfig(BaseModel):
port: int = 61613


class EnvironmentConfig(BaseModel):
class EnvironmentConfig(BlueapiBaseModel):
"""
Config for the RunEngine environment
"""

startup_script: Union[Path, str] = "blueapi.startup.example"


class LoggingConfig(BaseModel):
class LoggingConfig(BlueapiBaseModel):
level: str = "INFO"


class ApplicationConfig(BaseModel):
class ApplicationConfig(BlueapiBaseModel):
"""
Config for the worker application as a whole. Root of
config tree.
Expand Down
6 changes: 4 additions & 2 deletions src/blueapi/core/bluesky_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from bluesky.utils import Msg
from pydantic import BaseModel, Field

from blueapi.utils import BlueapiBaseModel

try:
from typing import Protocol, runtime_checkable
except ImportError:
Expand Down Expand Up @@ -79,7 +81,7 @@ def is_bluesky_plan_generator(func: PlanGenerator) -> bool:
)


class Plan(BaseModel):
class Plan(BlueapiBaseModel):
"""
A plan that can be run
"""
Expand All @@ -90,7 +92,7 @@ class Plan(BaseModel):
)


class DataEvent(BaseModel):
class DataEvent(BlueapiBaseModel):
"""
Event representing collection of some data. Conforms to the Bluesky event model:
https://github.com/bluesky/event-model
Expand Down
8 changes: 2 additions & 6 deletions src/blueapi/core/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

from bluesky import RunEngine
from bluesky.protocols import Flyable, Readable
from pydantic import BaseConfig

from blueapi.utils import (
BlueapiPlanModelConfig,
TypeValidatorDefinition,
create_model_with_type_validators,
load_module_all,
Expand All @@ -28,10 +28,6 @@
LOGGER = logging.getLogger(__name__)


class PlanModelConfig(BaseConfig):
arbitrary_types_allowed = True


@dataclass
class BlueskyContext:
"""
Expand Down Expand Up @@ -122,7 +118,7 @@ def my_plan(a: int, b: str):
plan.__name__,
validators,
func=plan,
config=PlanModelConfig,
config=BlueapiPlanModelConfig,
)
self.plans[plan.__name__] = Plan(name=plan.__name__, model=model)
self.plan_functions[plan.__name__] = plan
Expand Down
17 changes: 9 additions & 8 deletions src/blueapi/service/model.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from typing import Iterable, List

from bluesky.protocols import HasName
from pydantic import BaseModel, Field
from pydantic import Field

from blueapi.core import BLUESKY_PROTOCOLS, Device, Plan
from blueapi.utils import BlueapiBaseModel

_UNKNOWN_NAME = "UNKNOWN"


class DeviceModel(BaseModel):
class DeviceModel(BlueapiBaseModel):
"""
Representation of a device
"""
Expand All @@ -30,23 +31,23 @@ def _protocol_names(device: Device) -> Iterable[str]:
yield protocol.__name__


class DeviceRequest(BaseModel):
class DeviceRequest(BlueapiBaseModel):
"""
A query for devices
"""

...


class DeviceResponse(BaseModel):
class DeviceResponse(BlueapiBaseModel):
"""
Response to a query for devices
"""

devices: List[DeviceModel] = Field(description="Devices available to use in plans")


class PlanModel(BaseModel):
class PlanModel(BlueapiBaseModel):
"""
Representation of a plan
"""
Expand All @@ -58,23 +59,23 @@ def from_plan(cls, plan: Plan) -> "PlanModel":
return cls(name=plan.name)


class PlanRequest(BaseModel):
class PlanRequest(BlueapiBaseModel):
"""
A query for plans
"""

...


class PlanResponse(BaseModel):
class PlanResponse(BlueapiBaseModel):
"""
Response to a query for plans
"""

plans: List[PlanModel] = Field(description="Plans available to use by a worker")


class TaskResponse(BaseModel):
class TaskResponse(BlueapiBaseModel):
"""
Acknowledgement that a task has started, includes its ID
"""
Expand Down
4 changes: 4 additions & 0 deletions src/blueapi/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .base_model import BlueapiBaseModel, BlueapiModelConfig, BlueapiPlanModelConfig
from .config import ConfigLoader
from .modules import load_module_all
from .serialization import serialize
Expand All @@ -11,4 +12,7 @@
"create_model_with_type_validators",
"TypeValidatorDefinition",
"serialize",
"BlueapiBaseModel",
"BlueapiModelConfig",
"BlueapiPlanModelConfig",
]
35 changes: 35 additions & 0 deletions src/blueapi/utils/base_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from pydantic import BaseConfig, BaseModel, Extra


def _to_camel(string: str) -> str:
DiamondJoseph marked this conversation as resolved.
Show resolved Hide resolved
words = string.split("_")
return words[0] + "".join(word.capitalize() for word in words[1:])


class BlueapiModelConfig(BaseConfig):
"""
Pydantic config for blueapi API models with
common config.
"""

alias_generator = _to_camel
extra = Extra.forbid


class BlueapiPlanModelConfig(BlueapiModelConfig):
"""
Pydantic config for plan parameters.
Includes arbitrary type config so that devices
can be parameters.
"""

arbitrary_types_allowed = True


class BlueapiBaseModel(BaseModel):
"""
Base class for blueapi API models.
Includes common config.
"""

Config = BlueapiModelConfig
12 changes: 7 additions & 5 deletions src/blueapi/worker/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
from typing import List, Mapping, Optional, Union

from bluesky.run_engine import RunEngineStateMachine
from pydantic import BaseModel, Field
from pydantic import Field
from super_state_machine.extras import PropertyMachine, ProxyString

from blueapi.utils import BlueapiBaseModel

# The RunEngine can return any of these three types as its state
RawRunEngineState = Union[PropertyMachine, ProxyString, str]

Expand Down Expand Up @@ -41,7 +43,7 @@ def from_bluesky_state(cls, bluesky_state: RawRunEngineState) -> "WorkerState":
return WorkerState(str(bluesky_state).upper())


class StatusView(BaseModel):
class StatusView(BlueapiBaseModel):
"""
A snapshot of a Status of an operation, optionally representing progress
"""
Expand Down Expand Up @@ -80,7 +82,7 @@ class StatusView(BaseModel):
)


class ProgressEvent(BaseModel):
class ProgressEvent(BlueapiBaseModel):
"""
Event describing the progress of processes within a running task,
such as moving motors and exposing detectors.
Expand All @@ -90,7 +92,7 @@ class ProgressEvent(BaseModel):
statuses: Mapping[str, StatusView] = Field(default_factory=dict)


class TaskStatus(BaseModel):
class TaskStatus(BlueapiBaseModel):
"""
Status of a task the worker is running.
"""
Expand All @@ -100,7 +102,7 @@ class TaskStatus(BaseModel):
task_failed: bool


class WorkerEvent(BaseModel):
class WorkerEvent(BlueapiBaseModel):
"""
Event describing the state of the worker and any tasks it's running.
Includes error and warning information.
Expand Down
3 changes: 2 additions & 1 deletion src/blueapi/worker/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
from pydantic import BaseModel, Field, parse_obj_as

from blueapi.core import BlueskyContext, Plan
from blueapi.utils import BlueapiBaseModel


# TODO: Make a TaggedUnion
class Task(ABC, BaseModel):
class Task(ABC, BlueapiBaseModel):
"""
Object that can run with a TaskContext
"""
Expand Down