Skip to content

Commit

Permalink
Merge branch 'chore_release-8.0.0' into 8.0.0-alpha.0-mergeback
Browse files Browse the repository at this point in the history
  • Loading branch information
sfoster1 authored and caila-marashaj committed Aug 8, 2024
2 parents 79143a8 + 284d1f8 commit cd54d90
Show file tree
Hide file tree
Showing 189 changed files with 5,733 additions and 1,868 deletions.
12 changes: 12 additions & 0 deletions api-client/src/dataFiles/getCsvFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { GET, request } from '../request'

import type { CsvFileDataResponse } from './types'
import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'

export function getCsvFile(
config: HostConfig,
fileId: string
): ResponsePromise<CsvFileDataResponse> {
return request<CsvFileDataResponse>(GET, `/dataFiles/${fileId}`, null, config)
}
1 change: 1 addition & 0 deletions api-client/src/dataFiles/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { getCsvFile } from './getCsvFile'
export { getCsvFileRaw } from './getCsvFileRaw'
export { uploadCsvFile } from './uploadCsvFile'

Expand Down
4 changes: 3 additions & 1 deletion api-client/src/dataFiles/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ export interface CsvFileData {
name: string
}

export interface UploadedCsvFileResponse {
export interface CsvFileDataResponse {
data: CsvFileData
}

export type UploadedCsvFileResponse = CsvFileDataResponse

export interface UploadedCsvFilesResponse {
data: CsvFileData[]
}
Expand Down
19 changes: 19 additions & 0 deletions api-client/src/runs/commands/getRunCommandErrors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { GET, request } from '../../request'

import type { ResponsePromise } from '../../request'
import type { HostConfig } from '../../types'
import type { GetCommandsParams, RunCommandErrors } from '../types'

export function getRunCommandErrors(
config: HostConfig,
runId: string,
params: GetCommandsParams
): ResponsePromise<RunCommandErrors> {
return request<RunCommandErrors>(
GET,
`/runs/${runId}/commandErrors`,
null,
config,
params
)
}
7 changes: 6 additions & 1 deletion api-client/src/runs/commands/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import type { RunTimeCommand } from '@opentrons/shared-data'
import type { RunTimeCommand, RunCommandError } from '@opentrons/shared-data'

export interface GetCommandsParams {
cursor: number | null // the index of the command at the center of the window
pageLength: number // the number of items to include
}

export interface RunCommandErrors {
data: RunCommandError[]
meta: GetCommandsParams & { totalLength: number }
}

// NOTE: this incantation allows us to omit a key from each item in a union distributively
// this means we can, for example, maintain the associated commandType and params after the Omit is applied
type DistributiveOmit<T, K extends keyof T> = T extends any ? Omit<T, K> : never
Expand Down
1 change: 1 addition & 0 deletions api-client/src/runs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { getCommand } from './commands/getCommand'
export { getCommands } from './commands/getCommands'
export { getCommandsAsPreSerializedList } from './commands/getCommandsAsPreSerializedList'
export { createRunAction } from './createRunAction'
export { getRunCommandErrors } from './commands/getRunCommandErrors'
export * from './createLabwareOffset'
export * from './createLabwareDefinition'
export * from './constants'
Expand Down
5 changes: 5 additions & 0 deletions api/docs/v2/versioning.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ This table lists the correspondence between Protocol API versions and robot soft
Changes in API Versions
=======================

Version 2.20
------------

- You can now call :py:obj:`.ProtocolContext.define_liquid()` without supplying a ``description`` or ``display_color``.

Version 2.19
------------

Expand Down
20 changes: 20 additions & 0 deletions api/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ log][]. For a list of currently known issues, please see the [Opentrons issue tr
[technical change log]: https://github.com/Opentrons/opentrons/releases
[opentrons issue tracker]: https://github.com/Opentrons/opentrons/issues?q=is%3Aopen+is%3Aissue+label%3Abug

By installing and using Opentrons software, you agree to the Opentrons End-User License Agreement (EULA). You can view the EULA at [opentrons.com/eula](https://opentrons.com/eula).

---

## Opentrons Robot Software Changes in 8.0.0

Welcome to the v8.0.0 release of the Opentrons robot software!

### New Features

- Create, store, and run quick transfers on Flex.
- Define and use CSV runtime parameters in Python protocols.
- Detect the presence or absence of liquid in a well (Flex pipettes only), and continue or pause the protocol based on the result.
- Automatically pause Flex protocol runs when detecting overpressure, allowing for error recovery and run resumption.

### Improved Features

- Provides more partial tip pickup configurations. All multi-channel pipettes now support single and partial column pickup, and the Flex 96-channel pipette now supports row pickup.
- Improves homing behavior when a Flex protocol completes or is canceled with liquid-filled tips attached to the pipette.

---

## Opentrons Robot Software Changes in 7.5.0
Expand Down
2 changes: 1 addition & 1 deletion api/src/opentrons/cli/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ async def _do_analyze(protocol_source: ProtocolSource) -> RunResult:
protocol_source=protocol_source,
parse_mode=ParseMode.NORMAL,
run_time_param_values=None,
run_time_param_files=None,
run_time_param_paths=None,
)
except Exception as error:
err_id = "analysis-setup-error"
Expand Down
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
2 changes: 2 additions & 0 deletions api/src/opentrons/protocol_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from opentrons.protocols.parameters.exceptions import (
RuntimeParameterRequired as RuntimeParameterRequiredError,
)
from opentrons.protocols.parameters.csv_parameter_interface import CSVParameter

from .protocol_context import ProtocolContext
from .deck import Deck
Expand Down Expand Up @@ -74,6 +75,7 @@
"ALL",
"OFF_DECK",
"RuntimeParameterRequiredError",
"CSVParameter",
# For internal Opentrons use only:
"create_protocol_context",
"ProtocolEngineCoreRequiredError",
Expand Down
21 changes: 12 additions & 9 deletions api/src/opentrons/protocol_api/_parameter_context.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Parameter context for python protocols."""

from typing import List, Optional, Union, Dict

from opentrons.protocols.api_support.types import APIVersion
from opentrons.protocols.api_support.util import requires_version
from opentrons.protocols.parameters import (
parameter_definition,
csv_parameter_definition,
Expand All @@ -19,7 +19,7 @@
from opentrons.protocol_engine.types import (
RunTimeParameter,
PrimitiveRunTimeParamValuesType,
CSVRunTimeParamFilesType,
CSVRuntimeParamPaths,
FileInfo,
)

Expand Down Expand Up @@ -169,6 +169,7 @@ def add_str(
)
self._parameters[parameter.variable_name] = parameter

@requires_version(2, 20)
def add_csv_file(
self,
display_name: str,
Expand Down Expand Up @@ -218,15 +219,15 @@ def set_parameters(
parameter.value = validated_value

def initialize_csv_files(
self, run_time_param_file_overrides: CSVRunTimeParamFilesType
self, run_time_param_file_overrides: CSVRuntimeParamPaths
) -> None:
"""Initializes the files for CSV parameters.
:meta private:
This is intended for Opentrons internal use only and is not a guaranteed API.
"""
for variable_name, file_id in run_time_param_file_overrides.items():
for variable_name, file_path in run_time_param_file_overrides.items():
try:
parameter = self._parameters[variable_name]
except KeyError:
Expand All @@ -241,10 +242,12 @@ def initialize_csv_files(
f" but '{variable_name}' is not a CSV parameter."
)

parameter.file_info = FileInfo(id=file_id, name="")
# TODO (spp, 2024-07-16): set the file name and assign the file as parameter.value.
# Most likely, we will be creating a temporary file copy of the original
# to pass onto the protocol context
# The parent folder in the path will be the file ID, so we can use that to resolve that here
file_id = file_path.parent.name
file_name = file_path.name

parameter.file_info = FileInfo(id=file_id, name=file_name)
parameter.value = file_path

def export_parameters_for_analysis(self) -> List[RunTimeParameter]:
"""Exports all parameters into a protocol engine models for reporting in analysis.
Expand All @@ -269,7 +272,7 @@ def export_parameters_for_protocol(self) -> Parameters:
for parameter in self._parameters.values():
value: UserFacingTypes
if isinstance(parameter, csv_parameter_definition.CSVParameterDefinition):
value = parameter.as_csv_parameter_interface()
value = parameter.as_csv_parameter_interface(self._api_version)
else:
value = parameter.value
parameters_for_protocol[parameter.variable_name] = value
Expand Down
53 changes: 50 additions & 3 deletions api/src/opentrons/protocol_api/protocol_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@
]


class _Unset:
"""A sentinel value for when no value has been supplied for an argument,
when `None` is already taken for some other meaning.
User code should never use this explicitly.
"""

pass


class ProtocolContext(CommandPublisher):
"""A context for the state of a protocol.
Expand Down Expand Up @@ -1197,17 +1207,54 @@ def set_rail_lights(self, on: bool) -> None:

@requires_version(2, 14)
def define_liquid(
self, name: str, description: Optional[str], display_color: Optional[str]
self,
name: str,
description: Union[str, None, _Unset] = _Unset(),
display_color: Union[str, None, _Unset] = _Unset(),
) -> Liquid:
# This first line of the docstring overrides the method signature in our public
# docs, which would otherwise have the `_Unset()`s expanded to a bunch of junk.
"""
define_liquid(self, name: str, description: Optional[str] = None, display_color: Optional[str] = None)
Define a liquid within a protocol.
:param str name: A human-readable name for the liquid.
:param str description: An optional description of the liquid.
:param str display_color: An optional hex color code, with hash included, to represent the specified liquid. Standard three-value, four-value, six-value, and eight-value syntax are all acceptable.
:param Optional[str] description: An optional description of the liquid.
:param Optional[str] display_color: An optional hex color code, with hash included,
to represent the specified liquid. For example, ``"#48B1FA"``.
Standard three-value, four-value, six-value, and eight-value syntax are all
acceptable.
:return: A :py:class:`~opentrons.protocol_api.Liquid` object representing the specified liquid.
.. versionchanged:: 2.20
You can now omit the ``description`` and ``display_color`` arguments.
Formerly, when you didn't want to provide values, you had to supply
``description=None`` and ``display_color=None`` explicitly.
"""
desc_and_display_color_omittable_since = APIVersion(2, 20)
if isinstance(description, _Unset):
if self._api_version < desc_and_display_color_omittable_since:
raise APIVersionError(
api_element="Calling `define_liquid()` without a `description`",
current_version=str(self._api_version),
until_version=str(desc_and_display_color_omittable_since),
message="Use a newer API version or explicitly supply `description=None`.",
)
else:
description = None
if isinstance(display_color, _Unset):
if self._api_version < desc_and_display_color_omittable_since:
raise APIVersionError(
api_element="Calling `define_liquid()` without a `display_color`",
current_version=str(self._api_version),
until_version=str(desc_and_display_color_omittable_since),
message="Use a newer API version or explicitly supply `display_color=None`.",
)
else:
display_color = None

return self._core.define_liquid(
name=name,
description=description,
Expand Down
Loading

0 comments on commit cd54d90

Please sign in to comment.