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

python: Add a server listener that handles client message callbacks #226

Conversation

bryfox
Copy link
Contributor

@bryfox bryfox commented Feb 19, 2025

This adds a server listener interface to the Python SDK.

This is implemented as a Protocol in python; pyo3 does not support extending a Python class. To provide reasonable typing on start_server, that's now a wrapping function in the public package, to avoid the stub interface referencing the external type.

Since the ws-related code is starting to grow in python, I've moved related classes and functions into websocket_server.rs (from lib.rs). The exports are still in the top-level foxglove package for now.

To support the message data callback, this also adds support for the ClientPublish capability and supported_encodings.

I updated the existing live_visualization example to exercise this.

Copy link

linear bot commented Feb 19, 2025

@bryfox bryfox requested review from eloff and gasmith February 20, 2025 12:38
Copy link
Contributor

@eloff eloff left a comment

Choose a reason for hiding this comment

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

A couple questions about this. Overall the approach looks great.

#[pyo3(get)]
id: u32,
#[pyo3(get)]
topic: String,
Copy link
Contributor

Choose a reason for hiding this comment

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

This will create a Python string on every access, and involve at least two copies. One from rust str to owned string and a second on access to python string.

I don't think it will matter much to performance, since these are tiny, but we could save one copy by storing this a Python string and doing the conversion upfront.

Thoughts? We don't have to do this now, it's not a breaking change.

I'm more concerned about setting a good example for future code that we write than this particular case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 I changed this to PyString and now construct that directly from the &str.

};

let result: PyResult<()> = Python::with_gil(|py| {
let kwargs = PyDict::new(py);
Copy link
Contributor

Choose a reason for hiding this comment

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

We're creating this temporary dict here to call every callback. Why not use positional arguments?

The user can still choose to use kwargs if they want, but then at least they're aware of the overhead they're adding.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 updated

host: &str,
port: u16,
capabilities: Option<Vec<PyCapability>>,
server_listener: Option<Py<PyAny>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

If we're taking a PyAny here, why do we need to export PyServerListener to Python? I don't think we need it all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks. Leftover from before I realized it had to be implemented in Python directly.

@bryfox bryfox requested a review from eloff February 21, 2025 14:07
Copy link
Contributor

@eloff eloff left a comment

Choose a reason for hiding this comment

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

LGTM

@bryfox bryfox merged commit 4b4816b into main Feb 21, 2025
28 checks passed
@bryfox bryfox deleted the bryan/fg-10180-python-register-a-server-listener-with-client_message branch February 21, 2025 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants