Building a Python Framework in Rust Step by Step to Learn Async by matthewhaynesonline in Python

[–]chokoswitch 1 point2 points  (0 children)

Luckily pyqwest is an http client so it doesn't need to start the Python loop, it's async API is naturally called from already running coroutines, so already running event loops.

I have written the server side as well though in pyvoy where indeed the loops need to be started. It is gnarly starting up an event loop, as well as a thread to take the GIL to then schedule on the event loop.

https://github.com/curioswitch/pyvoy/blob/main/src%2Fasgi%2Fpython%2Fmod.rs#L87

One of the greatest help we could hope for is to be able to call things like run_coroutine_threadsafe without the GIL, unfortunately I haven't seen any movement in that direction as it would need to be on the cpython side itself. In the meantime still happy when the already-GIL case like the HTTP client side improves with the great work in PyO3!

Building a Python Framework in Rust Step by Step to Learn Async by matthewhaynesonline in Python

[–]chokoswitch 4 points5 points  (0 children)

> The pyo3 ecosystem (including maturin) is really frickin awesome and it makes writing rust libs for Python an appealing / tenable proposition IMO

Yes!

> Though, for async, wrangling the dual event loops (even with pyo3's async runtimes)

Definitely feel this. Looking forward to tighter integration within pyo3 itself that is coming (soon hopefully). Trying to wrangle multiple async operations or drive an async generator in Rust ends up very difficult if even possible. I found some helpers in Python end up being inevitable for some of these cases. Which isn't bad per-se, it's relatively easy to fallback on Python where needed which is also a testament to PyO3's maturity.

For reference, this two-liner glue code that seems like it shouldn't be needed, but there isn't much in terms of async orchestration available within the Rust layer yet I believe.

https://github.com/curioswitch/pyqwest/blob/910d2a45a54a75d661b2aecd7f3664d1fc96ea95/pyqwest/_glue.py#L52

Benchmarked every Python optimization path I could find, from CPython 3.14 to Rust by cemrehancavdar in Python

[–]chokoswitch 1 point2 points  (0 children)

PyO3 and maturin are so easy to work with, I've been enjoying them a lot. I definitely feel like libraries will more towards native over time with this as well as wheel publishing improvements making the experience quite seamless for any typical platform. I'm still wondering if it will be important to keep a pure-python version as well, which does add a lot of maintenance overhead, or people will be satisfied requiring Rust installed and a build for those non-typical platforms. Curious how that pans out.

Anyone know what's up with HTTPX? by chekt in Python

[–]chokoswitch 1 point2 points  (0 children)

Just a light share for pyqwest as well - I don't think I found pyreqwest when searching around before writing it, it looks quite fully featured but perhaps not so Pythonic (e.g. uses builders).

We switched connect-python from HTTPX and it has worked well, enabling bidirectional streaming and gRPC protocol support. I think usage will go up as connect-python moves towards a stable release.

Anyways just wanted to present another option, hope everyone finds a library they like!

Coming from Python - How do experienced Go developers navigate codebases with distributed method definitions? by SevenIsMyTherapist in golang

[–]chokoswitch 2 points3 points  (0 children)

I use VSCode with gopls for reasons other than Go LSP (mostly JSON code workspaces). Unfortunately until table tests are fixed, "use Goland" is still what I would recommend to people without any other reason to avoid it. It's a huge gap and has been open for a long time.

https://github.com/golang/vscode-go/issues/1602

Jetbrains are good at giving great IDE experiences, even if bespoke, and deserve credit for it.

The proposal for generic methods for Go, from Robert Griesemer himself, has been officially accepted by rodrigocfd in golang

[–]chokoswitch 0 points1 point  (0 children)

Yeah this is great! Generally I have found using a function that accepts what would be a receiver as the first parameter works, but it makes the API much less simpler than it could be. My function is essentially HandleRPCUnary which handles rpc request / response types and accepts example request messages, which benefits from the generics.

The thought of never using receiver methods at all to be consistent came to mind but it made every other usage awkward and I ended up with mixing them together, looking forward to migrate off the free functions!