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

feat(app, robot-server): add protocol receipt toasts and protocol ids endpoint #12725

Merged
merged 20 commits into from
May 22, 2023

Conversation

shlokamin
Copy link
Member

Overview

This fUlLsTaCk PR adds an endpoint that returns all protocol ids on the robot server, and uses it to render protocol receipt toasts in the app.

Closes RCORE-490 and RCORE-714

Test Plan

  • Sent protocol to a flex
  • Verified a protocol receipt toast shows up

Changelog

  • Add protocol ids endpoint to robot server
  • Render protocol receipt toast on ODD when a new protocol is added to a Flex

Review requests

See test plan

Risk assessment

Low

@codecov
Copy link

codecov bot commented May 17, 2023

Codecov Report

Merging #12725 (2f9b8d8) into edge (61ce223) will decrease coverage by 0.03%.
The diff coverage is 10.81%.

Impacted file tree graph

@@            Coverage Diff             @@
##             edge   #12725      +/-   ##
==========================================
- Coverage   73.35%   73.33%   -0.03%     
==========================================
  Files        2263     2266       +3     
  Lines       61497    61603     +106     
  Branches     6788     6811      +23     
==========================================
+ Hits        45112    45174      +62     
- Misses      14763    14813      +50     
+ Partials     1622     1616       -6     
Flag Coverage Δ
app 71.63% <10.71%> (-0.05%) ⬇️
react-api-client 71.30% <11.11%> (-1.55%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...ot-server/robot_server/protocols/protocol_store.py 94.73% <ø> (ø)
robot-server/robot_server/protocols/router.py 100.00% <ø> (ø)
...t-server/robot_server/service/json_api/response.py 100.00% <ø> (ø)
app/src/App/hooks.ts 12.76% <3.84%> (-11.05%) ⬇️
...api-client/src/protocols/useAllProtocolIdsQuery.ts 11.11% <11.11%> (ø)
app/src/App/OnDeviceDisplayApp.tsx 74.19% <100.00%> (+1.77%) ⬆️

... and 43 files with indirect coverage changes

@shlokamin shlokamin marked this pull request as ready for review May 17, 2023 19:23
@shlokamin shlokamin requested review from a team as code owners May 17, 2023 19:23
@shlokamin shlokamin requested review from smb2268, sfoster1, SyntaxColoring, b-cooper, jbleon95 and koji and removed request for a team and smb2268 May 17, 2023 19:23
@shlokamin shlokamin changed the title feat(robot-server, app): add protocol receipt toasts and protocol ids endpoint feat(app, robot-server): add protocol receipt toasts and protocol ids endpoint May 17, 2023
Copy link
Contributor

@vegano1 vegano1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me pending testing
Just left one comment
I'm also wondering if we will see the same notifications when the robot-app restarts? Since the odd only keeps track of what it's seen in memory

select_ids = sqlalchemy.select(protocol_table.c.id)
with self._sql_engine.begin() as transaction:
protocol_ids = transaction.execute(select_ids).scalars().all()
return protocol_ids
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe have a default value in case we fail to initialize protocol_id variable because of a failed query

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this question came up in another PR that I'm having trouble digging up, but I think the way that this is written now is good.

If the transaction fails, it will raise an exception out of the with ... block before protocol_ids is used. Providing a default value for protocol_ids would be misleading because it would never actually be returned.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

talked irl, leaving as is so the robot server returns an error if the database transaction fails

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I would agree with that, ignore my comment
In the case this does fail, we would return the appropriate HTTP response when handling the exception.

Copy link
Contributor

@brenthagen brenthagen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

Comment on lines 49 to 50
// wrapping protocolIds in a useMemo doesnt fix the issue that this eslint calls out
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this eslint disable is unused

Copy link
Contributor

@SyntaxColoring SyntaxColoring left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet. Here are a few requests for the server side, but this otherwise looks great.

I'm also curious about @vegano1's question:

I'm also wondering if we will see the same notifications when the robot-app restarts? Since the odd only keeps track of what it's seen in memory

robot-server/robot_server/protocols/protocol_store.py Outdated Show resolved Hide resolved
Copy link
Contributor

@SyntaxColoring SyntaxColoring May 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also add a /protocols/ids Tavern integration test? We don't need a whole new test file—we can just add a step to robot-server/tests/integration/http_api/protocols/test_upload.tavern.yaml, I think.

The specific thing that I'm concerned about is the ambiguity between GET /protocols/{id} and GET /protocols/ids. The functions need to be declared in the correct order for this to work, and I think the only way to cover that is with Tavern.

@@ -306,6 +305,28 @@ async def get_protocols(
)


@protocols_router.get(
path="/protocols/ids",
summary="Get uploaded protocol ids",
Copy link
Contributor

@SyntaxColoring SyntaxColoring May 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I may be a pain in the ass about docs:

Suggested change
summary="Get uploaded protocol ids",
summary="Get uploaded protocol ids",
description=(
"Get the IDs of all protocols stored on the server."
"\n\n"
"**Warning:**"
" This is an experimental endpoint and is only meant for internal use by Opentrons."
" We might remove it or change its behavior without warning."
),

This does two things.

First, the warning is because we're apparently publishing these docs now. Or publishing them imminently? I don't know.

Second, providing anything as a description prevents FastAPI from defaulting to the Python function docstring. We don't want it to do that because it has that "Args: protocol_store" internal junk.

Comment on lines +204 to +217
async def test_get_protocol_ids_no_protocols(
decoy: Decoy,
protocol_store: ProtocolStore,
) -> None:
"""It should return an empty collection response with no protocols loaded."""
decoy.when(protocol_store.get_all_ids()).then_return([])

result = await get_protocol_ids(protocol_store=protocol_store)

assert result.content.data == []
assert result.content.meta == MultiBodyMeta(cursor=0, totalLength=0)
assert result.status_code == 200


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you, but you could leave this test out, if you wanted.

Suggested change
async def test_get_protocol_ids_no_protocols(
decoy: Decoy,
protocol_store: ProtocolStore,
) -> None:
"""It should return an empty collection response with no protocols loaded."""
decoy.when(protocol_store.get_all_ids()).then_return([])
result = await get_protocol_ids(protocol_store=protocol_store)
assert result.content.data == []
assert result.content.meta == MultiBodyMeta(cursor=0, totalLength=0)
assert result.status_code == 200

Your other test_get_protocol_ids() test makes sure that the router will correctly pass along a ["protocol_id_1", "protocol_id_2"] result from the ProtocolStore to the HTTP client. Our thinking for this kind of thing has been that if it can do that, it will naturally work if the result is [] instead.

We can get away with this non-exhaustiveness because the router function is written as a "collaborator," just passing values from one thing to the other, not doing any logic of its own.

@shlokamin
Copy link
Member Author

shlokamin commented May 22, 2023

thx for the feedback max! im gonna merge this for now and address in a follow up so we can get this into 0.9.0 and start testing

I'm also wondering if we will see the same notifications when the robot-app restarts? Since the odd only keeps track of what it's seen in memory

the app only renders the toast if it's already refetched. meaning, it must have already refetched data and gotten a different diff in order to render the toast. so here is what happens:

  1. app renders, ids list is empty. no toast render
  2. app fetches ids for the first time, list has 4 ids cuz there were 4 protocols on the server (no toast render, because this is the first fetch)
  3. app refetches ids, list still has 4 ids (no toast render, because this is the first refetch)
  4. app refetches ids, list still has 4 ids (no toast render, because the diff is the same)

@shlokamin shlokamin merged commit bdb2bce into edge May 22, 2023
@shlokamin shlokamin deleted the robot_server-protocol-ids-endpoint branch May 22, 2023 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants