prometheus-api-client-python icon indicating copy to clipboard operation
prometheus-api-client-python copied to clipboard

Async Version of PrometheusConnect

Open RiviaAzusa opened this issue 8 months ago • 5 comments

@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!

RiviaAzusa avatar May 23 '25 06:05 RiviaAzusa

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!

  1. 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_values only need to be made in one place.

  2. Users who don't want async should not be forced to install additional dependencies.

  3. Existing function APIs should not be broken.

Does that sound reasonable?

chauhankaranraj avatar Jun 04 '25 04:06 chauhankaranraj

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:

  1. "What are the top 10 instances by CPU usage?"
  2. "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:

  1. Create a new AsyncPrometheusConnect class: The logic would be pretty similar to the original.
  2. Add async versions for each method in the existing PrometheusConnect class: For instance, def custom_query would get an async def acustom_query counterpart.
  3. Making the existing methods directly async... Honestly, I haven't found a really clean way to do this yet. While asyncio has to_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]?

RiviaAzusa avatar Jun 04 '25 05:06 RiviaAzusa

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

chauhankaranraj avatar Jun 05 '25 04:06 chauhankaranraj

@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.

4n4nd avatar Jun 09 '25 19:06 4n4nd