Async Version of PrometheusConnect
@4n4nd Hi~, I want to provide an async version of PrometheusConnect
Is your feature request related to a problem? Please describe.
Yes. The current implementation of PrometheusConnect uses the synchronous requests library, which can block the main thread and is not suitable for asynchronous applications (e.g., those using asyncio).
Describe the solution you'd like
I would like to propose an asynchronous version of PrometheusConnect, using an async HTTP client such as httpx or aiohttp. This would allow non-blocking communication with Prometheus servers and better integration with async Python applications.
Describe alternatives you've considered
Maybe can provide a async version named APrometheusConnect, user can free to choose one.
If you are open to this idea, I’d be happy to help implement and test it!
Thanks for opening this and for offering to help! IMO an async version could be very valuable.
But before we dive into implementation, could you please outline the use cases you had in mind where the current version is a blocker and async support would unblock users? Just wanna make sure we're taking on this non-trivial task for the right reasons :)
Regarding implementation, I think we should follow these guardrails - lmk what you think!
-
Avoid duplicating logic as much as possible so we don't end up with two completely separate code paths for the same use case. This way, future changes to something like
get_label_valuesonly need to be made in one place. -
Users who don't want async should not be forced to install additional dependencies.
-
Existing function APIs should not be broken.
Does that sound reasonable?
Thank you for your reply and your ideas!
Background: Right now, I'm using this library to build a service where a LLM talks to Prometheus.For example, the LLM might get questions like:
- "What are the top 10 instances by CPU usage?"
- "Is instance '10.xx.xx' alive? What's its status?"
The LLM then uses PromQL to query the results and answers the user based on that.
Why async? Essentially, with async, these I/O-bound Prometheus queries become non-blocking. This is crucial for my goal: efficiently running multiple PromQL queries or responding to several users simultaneously, all without stalling the main application.
How to implement it? Yeah, this definitely needs some good thought. The async version would mainly impact prometheus_api_client/prometheus_connect.py, and it would require adding aiohttp as a dependency.
I've got a few ideas on how to approach this:
-
Create a new
AsyncPrometheusConnectclass: The logic would be pretty similar to the original. -
Add async versions for each method in the existing
PrometheusConnectclass: For instance,def custom_querywould get anasync def acustom_querycounterpart. -
Making the existing methods directly async... Honestly, I haven't found a really clean way to do this yet. While
asynciohasto_thread, it doesn't feel truly native and still has some overhead.
I've actually put together a preliminary version of Option 1. You can check it out here (it still needs some tweaking): https://github.com/RiviaAzusa/Langchain-prometheus-clinet-toolkit/blob/async/prometheus_api_client/prometheus_connect_async.py
Regarding installation:
What do you think about modifying project.toml to offer an optional install, something like pip install prometheus-api-client[async]?
That's a very cool use case! I think async would be warranted for such applications.
I do need to give more thought to the implementation, but right off the bat option 1 seems the most reasonable. If there's enough overlap, it might makes sense to create a PrometheusConnect base class and have the current sync version and the new async version be its children.
What do you think about modifying project.toml to offer an optional install, something like pip install prometheus-api-client[async]?
Yep that's exactly what I was thinking
Thoughts? @4n4nd @harshad16 @yashvardhannanavati
@RiviaAzusa
Create a new AsyncPrometheusConnect class: The logic would be pretty similar to the original.
I think this solution makes the most sense. This won't affect existing users. There will definitely be duplicate code between the two classes (APC and PC), but once we have a stable implementation, we can plan to merge them.
Regarding installation:
What do you think about modifying project.toml to offer an optional install, something like pip install prometheus-api-client[async]?
I doubt another http client would be an issue. I think we should just add it as a requirement for now. We should definitely do this for other requirements like pandas and matplotlib tho.