Skip to content

Commit cc11492

Browse files
authored
Update transport model creation for new class structure (#223)
1 parent 5ceea05 commit cc11492

File tree

27 files changed

+190
-261
lines changed

27 files changed

+190
-261
lines changed

src/fastcs/demo/controller.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ controller:
55
port: 25565
66
num_ramp_controllers: 4
77
transport:
8-
- gql:
8+
- graphql:
99
host: localhost
1010
port: 8083
1111
log_level: info

src/fastcs/launch.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import inspect
33
import json
44
import signal
5-
from collections.abc import Coroutine
5+
from collections.abc import Coroutine, Sequence
66
from functools import partial
77
from pathlib import Path
88
from typing import Annotated, Any, Optional, TypeAlias, get_type_hints
@@ -13,27 +13,31 @@
1313
from ruamel.yaml import YAML
1414

1515
from fastcs import __version__
16+
from fastcs.transport.epics.ca.transport import EpicsCATransport
17+
from fastcs.transport.epics.pva.transport import EpicsPVATransport
18+
from fastcs.transport.graphql.transport import GraphQLTransport
19+
from fastcs.transport.rest.transport import RestTransport
20+
from fastcs.transport.tango.transport import TangoTransport
1621

1722
from .backend import Backend
1823
from .controller import Controller
1924
from .exceptions import LaunchError
2025
from .transport import Transport
21-
from .transport.epics.ca.options import EpicsCAOptions
22-
from .transport.epics.pva.options import EpicsPVAOptions
23-
from .transport.graphql.options import GraphQLOptions
24-
from .transport.rest.options import RestOptions
25-
from .transport.tango.options import TangoOptions
2626

2727
# Define a type alias for transport options
28-
TransportOptions: TypeAlias = list[
29-
EpicsPVAOptions | EpicsCAOptions | TangoOptions | RestOptions | GraphQLOptions
28+
TransportList: TypeAlias = list[
29+
EpicsPVATransport
30+
| EpicsCATransport
31+
| TangoTransport
32+
| RestTransport
33+
| GraphQLTransport
3034
]
3135

3236

3337
class FastCS:
3438
"""For launching a controller with given transport(s)."""
3539

36-
def __init__(self, controller: Controller, transports: list[Transport]):
40+
def __init__(self, controller: Controller, transports: Sequence[Transport]):
3741
self._loop = asyncio.get_event_loop()
3842
self._controller = controller
3943
self._backend = Backend(controller, self._loop)
@@ -45,13 +49,11 @@ def __init__(self, controller: Controller, transports: list[Transport]):
4549

4650
def create_docs(self) -> None:
4751
for transport in self._transports:
48-
if hasattr(transport.options, "docs"):
49-
transport.create_docs()
52+
transport.create_docs()
5053

5154
def create_gui(self) -> None:
5255
for transport in self._transports:
53-
if hasattr(transport.options, "gui"):
54-
transport.create_gui()
56+
transport.create_gui()
5557

5658
def run(self):
5759
serve = asyncio.ensure_future(self.serve())
@@ -231,7 +233,7 @@ def _extract_options_model(controller_class: type[Controller]) -> type[BaseModel
231233
if len(args) == 1:
232234
fastcs_options = create_model(
233235
f"{controller_class.__name__}",
234-
transport=(TransportOptions, ...),
236+
transport=(TransportList, ...),
235237
__config__={"extra": "forbid"},
236238
)
237239
elif len(args) == 2:
@@ -248,7 +250,7 @@ def _extract_options_model(controller_class: type[Controller]) -> type[BaseModel
248250
fastcs_options = create_model(
249251
f"{controller_class.__name__}",
250252
controller=(options_type, ...),
251-
transport=(TransportOptions, ...),
253+
transport=(TransportList, ...),
252254
__config__={"extra": "forbid"},
253255
)
254256
else:

src/fastcs/transport/__init__.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
from .epics.ca.options import EpicsCAOptions as EpicsCAOptions
1+
from .epics.ca.transport import EpicsCATransport as EpicsCATransport
22
from .epics.options import EpicsDocsOptions as EpicsDocsOptions
33
from .epics.options import EpicsGUIOptions as EpicsGUIOptions
44
from .epics.options import EpicsIOCOptions as EpicsIOCOptions
5-
from .epics.pva.options import EpicsPVAOptions as EpicsPVAOptions
6-
from .graphql.options import GraphQLOptions as GraphQLOptions
7-
from .graphql.options import GraphQLServerOptions as GraphQLServerOptions
8-
from .rest.options import RestOptions as RestOptions
9-
from .rest.options import RestServerOptions as RestServerOptions
5+
from .epics.pva.transport import EpicsPVATransport as EpicsPVATransport
6+
from .graphql.transport import GraphQLTransport as GraphQLTransport
7+
from .rest.transport import RestTransport as RestTransport
108
from .tango.options import TangoDSROptions as TangoDSROptions
11-
from .tango.options import TangoOptions as TangoOptions
9+
from .tango.transport import TangoTransport as TangoTransport
1210
from .transport import Transport as Transport

src/fastcs/transport/epics/ca/adapter.py renamed to src/fastcs/transport/epics/ca/transport.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,28 @@
11
import asyncio
2+
from dataclasses import dataclass, field
23
from typing import Any
34

45
from softioc import softioc
56

67
from fastcs.controller_api import ControllerAPI
7-
from fastcs.transport import Transport
88
from fastcs.transport.epics.ca.ioc import EpicsCAIOC
9-
from fastcs.transport.epics.ca.options import EpicsCAOptions
109
from fastcs.transport.epics.docs import EpicsDocs
1110
from fastcs.transport.epics.gui import EpicsGUI
11+
from fastcs.transport.epics.options import (
12+
EpicsDocsOptions,
13+
EpicsGUIOptions,
14+
EpicsIOCOptions,
15+
)
16+
from fastcs.transport.transport import Transport
1217

1318

19+
@dataclass
1420
class EpicsCATransport(Transport):
1521
"""Channel access transport."""
1622

17-
def __init__(self, options: EpicsCAOptions | None = None):
18-
self._options = options or EpicsCAOptions()
23+
docs: EpicsDocsOptions = field(default_factory=EpicsDocsOptions)
24+
gui: EpicsGUIOptions = field(default_factory=EpicsGUIOptions)
25+
ca_ioc: EpicsIOCOptions = field(default_factory=EpicsIOCOptions)
1926

2027
def initialise(
2128
self,
@@ -24,22 +31,14 @@ def initialise(
2431
) -> None:
2532
self._controller_api = controller_api
2633
self._loop = loop
27-
self._pv_prefix = self._options.ca_ioc.pv_prefix
28-
self._ioc = EpicsCAIOC(
29-
self._options.ca_ioc.pv_prefix,
30-
controller_api,
31-
self._options.ca_ioc,
32-
)
33-
34-
@property
35-
def options(self) -> EpicsCAOptions:
36-
return self._options
34+
self._pv_prefix = self.ca_ioc.pv_prefix
35+
self._ioc = EpicsCAIOC(self.ca_ioc.pv_prefix, controller_api, self.ca_ioc)
3736

3837
def create_docs(self) -> None:
39-
EpicsDocs(self._controller_api).create_docs(self._options.docs)
38+
EpicsDocs(self._controller_api).create_docs(self.docs)
4039

4140
def create_gui(self) -> None:
42-
EpicsGUI(self._controller_api, self._pv_prefix).create_gui(self._options.gui)
41+
EpicsGUI(self._controller_api, self._pv_prefix).create_gui(self.gui)
4342

4443
async def serve(self) -> None:
4544
print(f"Running FastCS IOC: {self._pv_prefix}")

src/fastcs/transport/epics/pva/options.py

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
11
import asyncio
2+
from dataclasses import dataclass, field
23

34
from fastcs.controller_api import ControllerAPI
4-
from fastcs.transport import Transport
55
from fastcs.transport.epics.docs import EpicsDocs
66
from fastcs.transport.epics.gui import PvaEpicsGUI
7-
from fastcs.transport.epics.pva.options import EpicsPVAOptions
7+
from fastcs.transport.epics.options import (
8+
EpicsDocsOptions,
9+
EpicsGUIOptions,
10+
EpicsIOCOptions,
11+
)
12+
from fastcs.transport.transport import Transport
813

914
from .ioc import P4PIOC
1015

1116

17+
@dataclass
1218
class EpicsPVATransport(Transport):
1319
"""PV access transport."""
1420

15-
def __init__(self, options: EpicsPVAOptions | None = None):
16-
self._options = options or EpicsPVAOptions()
21+
docs: EpicsDocsOptions = field(default_factory=EpicsDocsOptions)
22+
gui: EpicsGUIOptions = field(default_factory=EpicsGUIOptions)
23+
pva_ioc: EpicsIOCOptions = field(default_factory=EpicsIOCOptions)
1724

1825
def initialise(
1926
self,
2027
controller_api: ControllerAPI,
2128
loop: asyncio.AbstractEventLoop,
2229
) -> None:
2330
self._controller_api = controller_api
24-
self._pv_prefix = self.options.pva_ioc.pv_prefix
25-
self._ioc = P4PIOC(self.options.pva_ioc.pv_prefix, controller_api)
26-
27-
@property
28-
def options(self) -> EpicsPVAOptions:
29-
return self._options
31+
self._pv_prefix = self.pva_ioc.pv_prefix
32+
self._ioc = P4PIOC(self.pva_ioc.pv_prefix, controller_api)
3033

3134
async def serve(self) -> None:
3235
print(f"Running FastCS IOC: {self._pv_prefix}")
3336
await self._ioc.run()
3437

3538
def create_docs(self) -> None:
36-
EpicsDocs(self._controller_api).create_docs(self.options.docs)
39+
EpicsDocs(self._controller_api).create_docs(self.docs)
3740

3841
def create_gui(self) -> None:
39-
PvaEpicsGUI(self._controller_api, self._pv_prefix).create_gui(self.options.gui)
42+
PvaEpicsGUI(self._controller_api, self._pv_prefix).create_gui(self.gui)

src/fastcs/transport/graphql/adapter.py

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
from dataclasses import dataclass, field
1+
from dataclasses import dataclass
22

33

44
@dataclass
55
class GraphQLServerOptions:
66
host: str = "localhost"
77
port: int = 8080
88
log_level: str = "info"
9-
10-
11-
@dataclass
12-
class GraphQLOptions:
13-
"""Options for the GraphQL transport."""
14-
15-
gql: GraphQLServerOptions = field(default_factory=GraphQLServerOptions)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import asyncio
2+
from dataclasses import dataclass, field
3+
4+
from fastcs.controller_api import ControllerAPI
5+
from fastcs.transport.transport import Transport
6+
7+
from .graphql import GraphQLServer
8+
from .options import GraphQLServerOptions
9+
10+
11+
@dataclass
12+
class GraphQLTransport(Transport):
13+
"""GraphQL transport."""
14+
15+
graphql: GraphQLServerOptions = field(default_factory=GraphQLServerOptions)
16+
17+
def initialise(
18+
self,
19+
controller_api: ControllerAPI,
20+
loop: asyncio.AbstractEventLoop,
21+
):
22+
self._server = GraphQLServer(controller_api)
23+
24+
async def serve(self) -> None:
25+
await self._server.serve(self.graphql)

src/fastcs/transport/rest/adapter.py

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)