-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(api): add create_file_runner factory
- Loading branch information
Showing
12 changed files
with
330 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Protocol runner factory.""" | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
from opentrons.protocol_engine import ProtocolEngine | ||
from opentrons.protocols.runner import CommandTranslator | ||
|
||
from .abstract_file_runner import AbstractFileRunner | ||
from .json_file_runner import JsonFileRunner | ||
from .json_file_reader import JsonFileReader | ||
from .command_queue_worker import CommandQueueWorker | ||
from .protocol_file import ProtocolFileType, JsonProtocolFile | ||
|
||
|
||
def create_file_runner( | ||
file_type: Optional[ProtocolFileType], | ||
file_path: Optional[Path], | ||
engine: ProtocolEngine, | ||
) -> AbstractFileRunner: | ||
"""Construct a wired-up protocol runner instance. | ||
Arguments: | ||
file: Protocol file the runner will be using. If `None`, returns | ||
a basic runner for ProtocolEngine usage without a file. | ||
engine: The protocol engine interface the runner will use. | ||
Returns: | ||
A runner appropriate for the requested protocol type. | ||
""" | ||
file = None | ||
|
||
if file_path is not None and file_type == ProtocolFileType.JSON: | ||
file = JsonProtocolFile(file_path=file_path) | ||
|
||
if isinstance(file, JsonProtocolFile): | ||
return JsonFileRunner( | ||
file=file, | ||
protocol_engine=engine, | ||
file_reader=JsonFileReader(), | ||
command_translator=CommandTranslator(), | ||
command_queue_worker=CommandQueueWorker(), | ||
) | ||
|
||
raise NotImplementedError("Other runner types not yet supported") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
"""JSON file reading.""" | ||
|
||
from opentrons.protocols.models import JsonProtocol | ||
from .protocol_file import JsonProtocolFile | ||
|
||
|
||
class JsonFileReader: | ||
"""Reads and parses JSON protocol files.""" | ||
|
||
@staticmethod | ||
def read(file: JsonProtocolFile) -> JsonProtocol: | ||
"""Read and parse file into a JsonProtocol model.""" | ||
contents = file.file_path.read_text(encoding="utf-8") | ||
return JsonProtocol.parse_raw(contents) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
"""Test fixtures for opentrons.file_runner tests.""" | ||
import pytest | ||
|
||
from opentrons.protocols.models import JsonProtocol | ||
|
||
|
||
@pytest.fixture | ||
def json_protocol(json_protocol_dict: dict) -> JsonProtocol: | ||
"""Get a parsed JSON protocol model fixture.""" | ||
return JsonProtocol.parse_obj(json_protocol_dict) | ||
|
||
|
||
@pytest.fixture | ||
def json_protocol_dict(minimal_labware_def: dict) -> dict: | ||
"""Get a JSON protocol dictionary fixture.""" | ||
return { | ||
"schemaVersion": 3, | ||
"metadata": {}, | ||
"robot": {"model": "OT-2 Standard"}, | ||
"pipettes": {"leftPipetteId": {"mount": "left", "name": "p300_single"}}, | ||
"labware": { | ||
"trashId": { | ||
"slot": "12", | ||
"displayName": "Trash", | ||
"definitionId": "opentrons/opentrons_1_trash_1100ml_fixed/1", | ||
}, | ||
"tiprack1Id": { | ||
"slot": "1", | ||
"displayName": "Opentrons 96 Tip Rack 300 µL", | ||
"definitionId": "opentrons/opentrons_96_tiprack_300ul/1", | ||
}, | ||
"wellplate1Id": { | ||
"slot": "10", | ||
"displayName": "Corning 96 Well Plate 360 µL Flat", | ||
"definitionId": "opentrons/corning_96_wellplate_360ul_flat/1", | ||
}, | ||
}, | ||
"labwareDefinitions": { | ||
"opentrons/opentrons_1_trash_1100ml_fixed/1": minimal_labware_def, | ||
"opentrons/opentrons_96_tiprack_300ul/1": minimal_labware_def, | ||
"opentrons/corning_96_wellplate_360ul_flat/1": minimal_labware_def, | ||
}, | ||
"commands": [ | ||
{ | ||
"command": "pickUpTip", | ||
"params": { | ||
"pipette": "leftPipetteId", | ||
"labware": "tiprack1Id", | ||
"well": "A1", | ||
}, | ||
}, | ||
{ | ||
"command": "aspirate", | ||
"params": { | ||
"pipette": "leftPipetteId", | ||
"volume": 51, | ||
"labware": "wellplate1Id", | ||
"well": "B1", | ||
"offsetFromBottomMm": 10, | ||
"flowRate": 10, | ||
}, | ||
}, | ||
{ | ||
"command": "dispense", | ||
"params": { | ||
"pipette": "leftPipetteId", | ||
"volume": 50, | ||
"labware": "wellplate1Id", | ||
"well": "H1", | ||
"offsetFromBottomMm": 1, | ||
"flowRate": 50, | ||
}, | ||
}, | ||
], | ||
} |
19 changes: 19 additions & 0 deletions
19
api/tests/opentrons/file_runner/test_create_file_runner.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
"""Tests for the create_protocol_runner factory.""" | ||
from mock import MagicMock | ||
from pathlib import Path | ||
|
||
from opentrons.file_runner import ProtocolFileType, JsonFileRunner, create_file_runner | ||
|
||
|
||
def test_create_json_runner() -> None: | ||
"""It should be able to create a JSON file runner.""" | ||
file_type = ProtocolFileType.JSON | ||
file_path = Path("/dev/null") | ||
|
||
result = create_file_runner( | ||
file_type=file_type, | ||
file_path=file_path, | ||
engine=MagicMock(), | ||
) | ||
|
||
assert isinstance(result, JsonFileRunner) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
"""Integration tests for the JsonFileReader interface.""" | ||
import pytest | ||
import json | ||
from pathlib import Path | ||
|
||
from opentrons.protocols.models import JsonProtocol | ||
from opentrons.file_runner import JsonProtocolFile | ||
from opentrons.file_runner.json_file_reader import JsonFileReader | ||
|
||
|
||
@pytest.fixture | ||
def json_protocol_file( | ||
tmpdir: Path, | ||
json_protocol_dict: dict, | ||
) -> JsonProtocolFile: | ||
"""Get a JsonProtocolFile with JSON on-disk.""" | ||
file_path = tmpdir / "protocol.json" | ||
file_path.write_text(json.dumps(json_protocol_dict), encoding="utf-8") | ||
|
||
return JsonProtocolFile(file_path=file_path) | ||
|
||
|
||
@pytest.fixture | ||
def subject() -> JsonFileReader: | ||
"""Get a JsonFileReader test subject.""" | ||
return JsonFileReader() | ||
|
||
|
||
def test_reads_file( | ||
json_protocol_dict: dict, | ||
json_protocol_file: JsonProtocolFile, | ||
subject: JsonFileReader, | ||
) -> None: | ||
"""It should read a JSON file into a JsonProtocol model.""" | ||
result = subject.read(json_protocol_file) | ||
|
||
assert result == JsonProtocol.parse_obj(json_protocol_dict) |
Oops, something went wrong.