Skip to content

Commit

Permalink
style(api): Revise execute/simulate reference docstrings (#15901)
Browse files Browse the repository at this point in the history
Co-authored-by: Ed Cormany <[email protected]>
  • Loading branch information
SyntaxColoring and ecormany authored Aug 6, 2024
1 parent f45e6df commit e2d48dc
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 99 deletions.
74 changes: 37 additions & 37 deletions api/src/opentrons/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,23 @@ def get_protocol_api(
When this function is called, modules and instruments will be recached.
:param version: The API version to use. This must be lower than
``opentrons.protocol_api.MAX_SUPPORTED_VERSION``.
It may be specified either as a string (``'2.0'``) or
as a ``protocols.types.APIVersion``
(``APIVersion(2, 0)``).
``opentrons.protocol_api.MAX_SUPPORTED_VERSION``.
It may be specified either as a string (``'2.0'``) or
as a ``protocols.types.APIVersion``
(``APIVersion(2, 0)``).
:param bundled_labware: If specified, a mapping from labware names to
labware definitions for labware to consider in the
protocol. Note that if you specify this, _only_
labware in this argument will be allowed in the
protocol. This is preparation for a beta feature
and is best not used.
labware definitions for labware to consider in the
protocol. Note that if you specify this, *only*
labware in this argument will be allowed in the
protocol. This is preparation for a beta feature
and is best not used.
:param bundled_data: If specified, a mapping from filenames to contents
for data to be available in the protocol from
:py:obj:`opentrons.protocol_api.ProtocolContext.bundled_data`.
for data to be available in the protocol from
:py:obj:`opentrons.protocol_api.ProtocolContext.bundled_data`.
:param extra_labware: A mapping from labware load names to custom labware definitions.
If this is ``None`` (the default), and this function is called on a robot,
it will look for labware in the ``labware`` subdirectory of the Jupyter
data directory.
If this is ``None`` (the default), and this function is called on a robot,
it will look for labware in the ``labware`` subdirectory of the Jupyter
data directory.
:return: The protocol context.
"""
if isinstance(version, str):
Expand Down Expand Up @@ -313,18 +313,18 @@ def execute(
:param protocol_file: The protocol file to execute
:param protocol_name: The name of the protocol file. This is required
internally, but it may not be a thing we can get
from the protocol_file argument.
internally, but it may not be a thing we can get
from the ``protocol_file`` argument.
:param propagate_logs: Whether this function should allow logs from the
Opentrons stack to propagate up to the root handler.
This can be useful if you're integrating this
function in a larger application, but most logs that
occur during protocol simulation are best associated
with the actions in the protocol that cause them.
Default: ``False``
Opentrons stack to propagate up to the root handler.
This can be useful if you're integrating this
function in a larger application, but most logs that
occur during protocol simulation are best associated
with the actions in the protocol that cause them.
Default: ``False``
:param log_level: The level of logs to emit on the command line:
``"debug"``, ``"info"``, ``"warning"``, or ``"error"``.
Defaults to ``"warning"``.
``"debug"``, ``"info"``, ``"warning"``, or ``"error"``.
Defaults to ``"warning"``.
:param emit_runlog: A callback for printing the run log. If specified, this
will be called whenever a command adds an entry to the
run log, which can be used for display and progress
Expand Down Expand Up @@ -353,17 +353,17 @@ def execute(
``KeyError``.
:param custom_labware_paths: A list of directories to search for custom labware.
Loads valid labware from these paths and makes them available
to the protocol context. If this is ``None`` (the default), and
this function is called on a robot, it will look in the ``labware``
subdirectory of the Jupyter data directory.
Loads valid labware from these paths and makes them available
to the protocol context. If this is ``None`` (the default), and
this function is called on a robot, it will look in the ``labware``
subdirectory of the Jupyter data directory.
:param custom_data_paths: A list of directories or files to load custom
data files from. Ignored if the apiv2 feature
flag if not set. Entries may be either files or
directories. Specified files and the
non-recursive contents of specified directories
are presented by the protocol context in
``ProtocolContext.bundled_data``.
data files from. Ignored if the apiv2 feature
flag if not set. Entries may be either files or
directories. Specified files and the
non-recursive contents of specified directories
are presented by the protocol context in
``ProtocolContext.bundled_data``.
"""
stack_logger = logging.getLogger("opentrons")
stack_logger.propagate = propagate_logs
Expand Down Expand Up @@ -457,10 +457,10 @@ def main() -> int:
"""Handler for command line invocation to run a protocol.
:param argv: The arguments the program was invoked with; this is usually
:py:obj:`sys.argv` but if you want to override that you can.
:py:obj:`sys.argv` but if you want to override that you can.
:returns int: A success or failure value suitable for use as a shell
return code passed to :py:obj:`sys.exit` (0 means success,
anything else is a kind of failure).
return code passed to :py:obj:`sys.exit` (0 means success,
anything else is a kind of failure).
"""
parser = argparse.ArgumentParser(
prog="opentrons_execute", description="Run an OT-2 protocol"
Expand Down
129 changes: 67 additions & 62 deletions api/src/opentrons/simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,9 @@ def get_protocol_api(
use_virtual_hardware: bool = True,
) -> protocol_api.ProtocolContext:
"""
Build and return a ``protocol_api.ProtocolContext``
connected to Virtual Smoothie.
Build and return a ``protocol_api.ProtocolContext`` that simulates robot control.
This can be used to run protocols from interactive Python sessions
This can be used to simulate protocols from interactive Python sessions
such as Jupyter or an interpreter on the command line:
.. code-block:: python
Expand All @@ -242,28 +241,31 @@ def get_protocol_api(
>>> instr.home()
:param version: The API version to use. This must be lower than
``opentrons.protocol_api.MAX_SUPPORTED_VERSION``.
It may be specified either as a string (``'2.0'``) or
as a ``protocols.types.APIVersion``
(``APIVersion(2, 0)``).
``opentrons.protocol_api.MAX_SUPPORTED_VERSION``.
It may be specified either as a string (``'2.0'``) or
as a ``protocols.types.APIVersion``
(``APIVersion(2, 0)``).
:param bundled_labware: If specified, a mapping from labware names to
labware definitions for labware to consider in the
protocol. Note that if you specify this, _only_
labware in this argument will be allowed in the
protocol. This is preparation for a beta feature
and is best not used.
labware definitions for labware to consider in the
protocol. Note that if you specify this, *only*
labware in this argument will be allowed in the
protocol. This is preparation for a beta feature
and is best not used.
:param bundled_data: If specified, a mapping from filenames to contents
for data to be available in the protocol from
:py:obj:`opentrons.protocol_api.ProtocolContext.bundled_data`.
for data to be available in the protocol from
:py:obj:`opentrons.protocol_api.ProtocolContext.bundled_data`.
:param extra_labware: A mapping from labware load names to custom labware definitions.
If this is ``None`` (the default), and this function is called on a robot,
it will look for labware in the ``labware`` subdirectory of the Jupyter
data directory.
:param hardware_simulator: If specified, a hardware simulator instance.
If this is ``None`` (the default), and this function is called on a robot,
it will look for labware in the ``labware`` subdirectory of the Jupyter
data directory.
:param hardware_simulator: This is only for internal use by Opentrons. If specified,
it's a hardware simulator instance to reuse instead of creating a fresh one.
:param robot_type: The type of robot to simulate: either ``"Flex"`` or ``"OT-2"``.
If you're running this function on a robot, the default is the type of that
robot. Otherwise, the default is ``"OT-2"``, for backwards compatibility.
:param use_virtual_hardware: If true, use the protocol engines virtual hardware, if false use the lower level hardware simulator.
If you're running this function on a robot, the default is the type of that
robot. Otherwise, the default is ``"OT-2"``, for backwards compatibility.
:param use_virtual_hardware: This is only for internal use by Opentrons.
If ``True``, use the Protocol Engine's virtual hardware. If ``False``, use the
lower level hardware simulator.
:return: The protocol context.
"""
if isinstance(version, str):
Expand Down Expand Up @@ -321,7 +323,7 @@ def get_protocol_api(
hardware_api=checked_hardware,
bundled_data=bundled_data,
extra_labware=extra_labware,
use_virtual_hardware=use_virtual_hardware,
use_pe_virtual_hardware=use_virtual_hardware,
)

# Intentional difference from execute.get_protocol_api():
Expand Down Expand Up @@ -441,15 +443,15 @@ def simulate(
"""
Simulate the protocol itself.
This is a one-stop function to simulate a protocol, whether python or json,
no matter the api version, from external (i.e. not bound up in other
This is a one-stop function to simulate a protocol, whether Python or JSON,
no matter the API version, from external (i.e. not bound up in other
internal server infrastructure) sources.
To simulate an opentrons protocol from other places, pass in a file like
object as protocol_file; this function either returns (if the simulation
To simulate an opentrons protocol from other places, pass in a file-like
object as ``protocol_file``; this function either returns (if the simulation
has no problems) or raises an exception.
To call from the command line use either the autogenerated entrypoint
To call from the command line, use either the autogenerated entrypoint
``opentrons_simulate`` (``opentrons_simulate.exe``, on windows) or
``python -m opentrons.simulate``.
Expand Down Expand Up @@ -480,36 +482,37 @@ def simulate(
:param protocol_file: The protocol file to simulate.
:param file_name: The name of the file
:param custom_labware_paths: A list of directories to search for custom labware.
Loads valid labware from these paths and makes them available
to the protocol context. If this is ``None`` (the default), and
this function is called on a robot, it will look in the ``labware``
subdirectory of the Jupyter data directory.
Loads valid labware from these paths and makes them available
to the protocol context. If this is ``None`` (the default), and
this function is called on a robot, it will look in the ``labware``
subdirectory of the Jupyter data directory.
:param custom_data_paths: A list of directories or files to load custom
data files from. Ignored if the apiv2 feature
flag if not set. Entries may be either files or
directories. Specified files and the
non-recursive contents of specified directories
are presented by the protocol context in
``protocol_api.ProtocolContext.bundled_data``.
:param hardware_simulator_file_path: A path to a JSON file defining a
hardware simulator.
data files from. Ignored if the apiv2 feature
flag if not set. Entries may be either files or
directories. Specified files and the
non-recursive contents of specified directories
are presented by the protocol context in
``protocol_api.ProtocolContext.bundled_data``.
:param hardware_simulator_file_path: A path to a JSON file defining the simulated
hardware. This is mainly for internal use by Opentrons, and is not necessary
to simulate protocols.
:param duration_estimator: For internal use only.
Optional duration estimator object.
Optional duration estimator object.
:param propagate_logs: Whether this function should allow logs from the
Opentrons stack to propagate up to the root handler.
This can be useful if you're integrating this
function in a larger application, but most logs that
occur during protocol simulation are best associated
with the actions in the protocol that cause them.
Default: ``False``
Opentrons stack to propagate up to the root handler.
This can be useful if you're integrating this
function in a larger application, but most logs that
occur during protocol simulation are best associated
with the actions in the protocol that cause them.
Default: ``False``
:param log_level: The level of logs to capture in the run log:
``"debug"``, ``"info"``, ``"warning"``, or ``"error"``.
Defaults to ``"warning"``.
``"debug"``, ``"info"``, ``"warning"``, or ``"error"``.
Defaults to ``"warning"``.
:returns: A tuple of a run log for user output, and possibly the required
data to write to a bundle to bundle this protocol. The bundle is
only emitted if bundling is allowed
and this is an unbundled Protocol API
v2 python protocol. In other cases it is None.
data to write to a bundle to bundle this protocol. The bundle is
only emitted if bundling is allowed
and this is an unbundled Protocol API
v2 python protocol. In other cases it is None.
"""
stack_logger = logging.getLogger("opentrons")
stack_logger.propagate = propagate_logs
Expand Down Expand Up @@ -642,8 +645,7 @@ def get_arguments(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
Useful if you want to use this module as a component of another CLI program
and want to add its arguments.
:param parser: A parser to add arguments to. If not specified, one will be
created.
:param parser: A parser to add arguments to. If not specified, one will be created.
:returns argparse.ArgumentParser: The parser with arguments added.
"""
parser.add_argument(
Expand Down Expand Up @@ -800,7 +802,7 @@ def _create_live_context_pe(
deck_type: str,
extra_labware: Dict[str, "LabwareDefinitionDict"],
bundled_data: Optional[Dict[str, bytes]],
use_virtual_hardware: bool = True,
use_pe_virtual_hardware: bool = True,
) -> ProtocolContext:
"""Return a live ProtocolContext that controls the robot through ProtocolEngine."""
assert api_version >= ENGINE_CORE_API_VERSION
Expand All @@ -810,7 +812,7 @@ def _create_live_context_pe(
create_protocol_engine_in_thread(
hardware_api=hardware_api_wrapped,
config=_get_protocol_engine_config(
robot_type, virtual=use_virtual_hardware
robot_type, use_pe_virtual_hardware=use_pe_virtual_hardware
),
error_recovery_policy=error_recovery_policy.never_recover,
drop_tips_after_run=False,
Expand Down Expand Up @@ -916,7 +918,9 @@ async def run(protocol_source: ProtocolSource) -> _SimulateResult:
hardware_api_wrapped = hardware_api.wrapped()
protocol_engine = await create_protocol_engine(
hardware_api=hardware_api_wrapped,
config=_get_protocol_engine_config(robot_type, virtual=True),
config=_get_protocol_engine_config(
robot_type, use_pe_virtual_hardware=True
),
error_recovery_policy=error_recovery_policy.never_recover,
load_fixed_trash=should_load_fixed_trash(protocol_source.config),
)
Expand Down Expand Up @@ -974,15 +978,17 @@ async def run(protocol_source: ProtocolSource) -> _SimulateResult:
return asyncio.run(run(protocol_source))


def _get_protocol_engine_config(robot_type: RobotType, virtual: bool) -> Config:
def _get_protocol_engine_config(
robot_type: RobotType, use_pe_virtual_hardware: bool
) -> Config:
"""Return a Protocol Engine config to execute protocols on this device."""
return Config(
robot_type=robot_type,
deck_type=DeckType(deck_type_for_simulation(robot_type)),
ignore_pause=True,
use_virtual_pipettes=virtual,
use_virtual_modules=virtual,
use_virtual_gripper=virtual,
use_virtual_pipettes=use_pe_virtual_hardware,
use_virtual_modules=use_pe_virtual_hardware,
use_virtual_gripper=use_pe_virtual_hardware,
use_simulated_deck_config=True,
)

Expand All @@ -1005,7 +1011,6 @@ def main() -> int:
parser = get_arguments(parser)

args = parser.parse_args()
# Try to migrate api v1 containers if needed

# TODO(mm, 2022-12-01): Configure the DurationEstimator with the correct deck type.
duration_estimator = DurationEstimator() if args.estimate_duration else None # type: ignore[no-untyped-call]
Expand Down

0 comments on commit e2d48dc

Please sign in to comment.