Skip to content

Conversation

maximpertsov
Copy link
Contributor

@maximpertsov maximpertsov commented May 25, 2023

Implements client-side sessions for the python sdk

TODO

  • Ensure in-progress actions are cancelled if the SDK is forcefully killed

Manual Testing

curl https://gist.githubusercontent.com/maximpertsov/acd5d9ddaaa835a000a310341cdfb1de/raw/0fe5f13d1cafef0eb39f7bfcb59556f7f21a53af/viam-python-sessions-testing.py > testing.py
  • Find your favorite robot with a drive-able base and replace the URI, SECRET, BASE_NAME constants in script above with the relevant parameters.

  • Run the following commands

poetry add -D aioconsole  # needed for the script above
make install && poetry run python testing.py
  • You should see output that looks like this:
2023-05-25 17:21:09,768         DEBUG   viam.rpc.dial (dial.py:188)     Creating new viam-rust-utils runtime
2023-05-25 17:21:09,770         DEBUG   viam.rpc.dial (dial.py:209)     Dialing <URI> using viam-rust-utils library
2023-05-25 17:21:11,492         INFO    viam.rpc.dial (dial.py:239)     Connecting to socket: <SOCKET>
2023-05-25 17:21:11,624         DEBUG   viam.sessions_client (sessions_client.py:128)   sent heartbeat successfully
Move in a direction (WASD) or Q to exit
2023-05-25 17:21:12,038         DEBUG   viam.sessions_client (sessions_client.py:128)   sent heartbeat successfully
2023-05-25 17:21:12,450         DEBUG   viam.sessions_client (sessions_client.py:128)   sent heartbeat successfully
2023-05-25 17:21:12,865         DEBUG   viam.sessions_client (sessions_client.py:128)   sent heartbeat successfully
2023-05-25 17:21:13,279         DEBUG   viam.sessions_client (sessions_client.py:128)   sent heartbeat successfully
...
  • Pressing W A S or D + ENTER should drive the base without any noticeable lag.

@maximpertsov maximpertsov marked this pull request as ready for review May 25, 2023 21:22
@maximpertsov maximpertsov requested a review from a team as a code owner May 25, 2023 21:22
@maximpertsov maximpertsov requested review from clintpurser and benjirewis and removed request for clintpurser May 25, 2023 21:22
@maximpertsov maximpertsov removed the request for review from benjirewis May 25, 2023 21:23
@maximpertsov maximpertsov marked this pull request as draft May 25, 2023 21:24
@maximpertsov maximpertsov marked this pull request as ready for review May 25, 2023 21:31
@maximpertsov maximpertsov requested review from edaniels and njooma May 25, 2023 21:31
@edaniels
Copy link
Contributor

edaniels commented May 26, 2023

why isn't this being implemented in rust-utils?

@maximpertsov
Copy link
Contributor Author

why isn't this being implemented in rust-utils?

the python sdk can still dial a robot directly without using rust-utils, so we need to implement it here to support sessions for that kind of connection.

@edaniels
Copy link
Contributor

why isn't this being implemented in rust-utils?

the python sdk can still dial a robot directly without using rust-utils, so we need to implement it here to support sessions for that kind of connection.

got it

Copy link
Contributor

@edaniels edaniels left a comment

Choose a reason for hiding this comment

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

LGTM assuming testing was done that the robot stopped the base once the python SDK was forcefully killed without warning

if self._disabled:
return

if event.method_name in [self.client.StartSession.name]:
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need to exempt the other methods at https://github.com/viamrobotics/rdk/blob/main/session/doc.go#L71?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah didn't see this before, will add

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@maximpertsov
Copy link
Contributor Author

maximpertsov commented May 26, 2023

LGTM assuming testing was done that the robot stopped the base once the python SDK was forcefully killed without warning

Yeah, let me try this with a longer-running command to confirm

EDIT: done - works as expected. If you run the following script and abort it, the robot will stop moving straight.

# imports / constants ...

async def connect():
    creds = Credentials(type="robot-location-secret", payload=SECRET)
    opts = RobotClient.Options(refresh_interval=0, dial_options=DialOptions(credentials=creds), log_level=DEBUG)
    return await RobotClient.at_address(URI, opts)

async def main():
    robot = await connect()
    base = Base.from_robot(robot, BASE_NAME)
    await base.move_straight(10000, 100)

if __name__ == "__main__":
    asyncio.run(main())

Copy link
Member

@njooma njooma left a comment

Choose a reason for hiding this comment

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

Just looked over for code quality, didn't actually test.

Looks good! Mostly nits

)


async def delay(coro, seconds):
Copy link
Member

Choose a reason for hiding this comment

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

there's a loop.call_later function that might be useful here:

loop = asyncio.get_running_loop()
loop.call_later(seconds, coro)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This looked promising, but unfortunately loop.call_later takes a sync callback and not a co-routine: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.call_later

if self._lock.locked():
return

LOGGER.debug("resetting session")
Copy link
Member

Choose a reason for hiding this comment

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

[nit] can we make all logs Sentence case please?

raise
else:
if response is None:
raise GRPCError(status=Status.INTERNAL, message="expected response to start session")
Copy link
Member

Choose a reason for hiding this comment

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

Same with error messages as with logs: Sentence case please

pyproject.toml Outdated
mypy-protobuf = "^3.4.0"
tox = "^4.5.1"
isort = "^5.12.0"
pytest-watcher = "^0.2.6"
Copy link
Member

Choose a reason for hiding this comment

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

[q] is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not strictly, but it was helpful to have this utility when I was spiking out unit tests. I can you remove if you prefer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Went ahead and removed

@maximpertsov maximpertsov merged commit 5451132 into viamrobotics:main May 30, 2023
@maximpertsov maximpertsov deleted the sessions-python-RSDK-2506 branch May 30, 2023 14:23
@maximpertsov
Copy link
Contributor Author

LGTM assuming testing was done that the robot stopped the base once the python SDK was forcefully killed without warning

Yeah, let me try this with a longer-running command to confirm

EDIT: done - works as expected. If you run the following script and abort it, the robot will stop moving straight.

# imports / constants ...

async def connect():
    creds = Credentials(type="robot-location-secret", payload=SECRET)
    opts = RobotClient.Options(refresh_interval=0, dial_options=DialOptions(credentials=creds), log_level=DEBUG)
    return await RobotClient.at_address(URI, opts)

async def main():
    robot = await connect()
    base = Base.from_robot(robot, BASE_NAME)
    await base.move_straight(10000, 100)

if __name__ == "__main__":
    asyncio.run(main())

For posterity, you should use base.set_power instead of base.move_straight for this test - set_power runs forever.

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.

3 participants