# Developing an extra - issue with http request

**URL:** <https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530>\
**Category:** Developers\
**Created:** [May 20, 2025, 8:09pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530 "2025-05-20T20:09:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![GoTVm](https://avatars.discourse-cdn.com/v4/letter/g/76d3ee/32.png) [@GoTVm](https://klipper.discourse.group/u/GoTVm)\
**Post date:** [May 20, 2025, 8:09pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/1 "2025-05-20T20:09:25Z")

</div>

Hey, I’m new to the development of Klipper add-ons, I’m trying to create an extra whose end goal is to read commands from a custom device’s serial port and translate them to “Klipper language”. Some of these commands require knowledge of the current state of the printer, namely the temperature and target of the heaters. Part of the test code I’ve written so far are these two functions, which quickly highlight the issue I’m facing

```auto
    def do_request(self):
        try:
            self.gcode.respond_info("Request attempt")
            now=time.time()
            data = requests.get("http://localhost/printer/objects/query?extruder&heater_bed", stream=True).json()

            status = data["result"]["status"]
            temps = {k: {"temperature": v["temperature"], "target": v["target"]}
                for k, v in status.items()
                if "temperature" in v and "target" in v}
            self.gcode.respond_info(str(temps))
            self.gcode.respond_info(str(time.time()-now))

        except Exception as e:
            self.gcode.respond_info(f"Request failed: {e}")
    
    def cmd_REQUEST(self, eventtime=None):
        #threading.Thread(target=self.do_request).start()
        self.do_request()
            
        return self.reactor.NEVER

```

If I run the request as is (call the REQUEST command from Klipper so it runs the do\_request function) the HTTP request times out, probably because I am attempting to stall Klipper for too long. If I set up a separate thread which runs the do\_request command, the request goes through correctly and I get the response I am looking for. Spawning a thread for each request is most likely not great, since there will be moments where I’ll need to handle a handful of requests a second.

All this said, is there a way to salvage this code, or am I on the wrong track entirely? How do I handle a request so it doesn’t halt Klipper?

---

<div class="post-metadata">

**Author:** ![flowerysong](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/flowerysong/32/10214_2.png) [@flowerysong](https://klipper.discourse.group/u/flowerysong)\
**Post date:** [May 20, 2025, 8:32pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/2 "2025-05-20T20:32:07Z")

</div>

First note that Klipper does not have an add-on system, so you should consider whether you can more cleanly accomplish your goal in another way (e.g. a separate daemon that reads commands and interacts with Klipper’s API.)

Secondly: why are you querying the API to get information from Klipper? The whole point of developing an unsupported Klipper add-on is to have access to Klipper internals. Just access the data you need.

---

<div class="post-metadata">

**Author:** ![GoTVm](https://avatars.discourse-cdn.com/v4/letter/g/76d3ee/32.png) [@GoTVm](https://klipper.discourse.group/u/GoTVm)\
**Post date:** [May 20, 2025, 8:37pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/3 "2025-05-20T20:37:50Z")

</div>

I am reading the Moonraker API because, after having a conversation with someone who knows Klipper far better than I do, that was their recommendation. Also because Klipper’s API is not very documented, or I havent been able to find a way to get even simple info like temperatures from it. A separate daemon might be a solution, simpler one as well, but I wanted to learn a little about the development of Klipper extras.

If you would be so kind to show me a snippet that “just accesses the data I need”, because I have barely been able to find any documentation, and [the only guide](https://dynamicmacros.3dcoded.xyz/extras/extras-intro/) I found barely scratches the surface (doesn’t show how to access printer data at all).

---

<div class="post-metadata">

**Author:** ![flowerysong](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/flowerysong/32/10214_2.png) [@flowerysong](https://klipper.discourse.group/u/flowerysong)\
**Post date:** [May 20, 2025, 8:41pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/4 "2025-05-20T20:41:16Z")

</div>

If you can’t read the existing code in [klipper/klippy/extras at master · Klipper3d/klipper · GitHub](https://github.com/Klipper3d/klipper/tree/master/klippy/extras) to figure out how to access printer data, you should not be thinking about trying to mess with Klipper internals.

---

<div class="post-metadata">

**Author:** ![GoTVm](https://avatars.discourse-cdn.com/v4/letter/g/76d3ee/32.png) [@GoTVm](https://klipper.discourse.group/u/GoTVm)\
**Post date:** [May 20, 2025, 8:49pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/5 "2025-05-20T20:49:35Z")

</div>

It’s not like a little documentation would hurt, eh? There is not a single mention of what objects I can access, how to access them (apart from “use lookup\_objects”) and then what to do with them. Not a single example on the whole world wide web.

I am just asking for some guidance, it’s the first time I work on this kinda stuff. I’m not asking whether you think I’m fit to “mess with Klipper internals”, as though I was going to compromise anything in large scale. Worst case scenario I thrash my own printer. That said, I asked a question, which you promptly didn’t answer and then just said I shouldn’t bother even trying.

Say I wanted to read the existing code, which of the components do you suggest I look into first?

---

<div class="post-metadata">

**Author:** ![3dcoded](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/3dcoded/32/20297_2.png) [@3dcoded](https://klipper.discourse.group/u/3dcoded)\
**Post date:** [May 20, 2025, 10:06pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/6 "2025-05-20T22:06:44Z")

</div>

@GoTVm ,

1. You might want to look at `heater_generic.py`

2. Example to get access to the heater bed, then you can get temperature from it.

3. I wrote a Klippy extra tutorial that you might find helpful.

> [@Klippy Extras Tutorial](https://klipper.discourse.group/t/klippy-extras-tutorial/18184):
>
> As an extension to [DynamicMacros](https://github.com/3DCoded/DynamicMacros), I recently wrote a Klippy extras tutorial, available [here](https://3dcoded.github.io/DynamicMacros/extras/extras-start/). It uses three examples of extras: Simple greeter bot Complex greeter bot [KlipperMaintenance](https://github.com/3DCoded/KlipperMaintenance) I would really appreciate any feedback. If anything is unclear or you think could be improved, please let me know here or in a [Documentation Issue](https://github.com/3DCoded/DynamicMacros/issues/new?assignees=&labels=documentation&projects=&template=documentation.md&title=%5BDOCS%5D).

* * *

Keep in mind that Klippy extras are unsupported officially, hence the lack of official docs around them.

---

<div class="post-metadata">

**Author:** ![GoTVm](https://avatars.discourse-cdn.com/v4/letter/g/76d3ee/32.png) [@GoTVm](https://klipper.discourse.group/u/GoTVm)\
**Post date:** [May 20, 2025, 10:23pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/7 "2025-05-20T22:23:33Z")

</div>

Thanks for the insight.

I followed your guide to set up the simple extra I have right now, but I don’t think you accessed any of the printer’s internal values in any of the three examples.

I thought extras were supported since they come stock with the Klipper installation, guess I was wrong; as I said, I’ve only ever used Klipper, never developed for it.

Is there a list of objects I can access with their respective parameters, or do you just get them from the different .py files? I see you used .smoothed\_temp, which I hadn’t seen mentioned anywhere before now. Another question I have regarding printer object access: say I try to access the extruder, I get a PrinterExtruder object (IIRC, I’m not at the computer right now). How do I know which arguments and methods I can call from that class?

---

<div class="post-metadata">

**Author:** ![3dcoded](https://yyz2.discourse-cdn.com/free1/user_avatar/klipper.discourse.group/3dcoded/32/20297_2.png) [@3dcoded](https://klipper.discourse.group/u/3dcoded)\
**Post date:** [May 20, 2025, 10:45pm UTC](https://klipper.discourse.group/t/developing-an-extra-issue-with-http-request/23530/8 "2025-05-20T22:45:30Z")

</div>

You can usually look in the extras folder for the objects you want to access. The `get_status()` method is a good place to find what state variables you can easily access.

Example:

> <https://github.com/Klipper3d/klipper/blob/master/klippy/extras/heaters.py#L143>

> [@GoTVm](#):
>
> How do I know which arguments and methods I can call from that class?

Like normal python, you can log the output of `dir(some_object)` or find the relevant source file.

> [@GoTVm](#):
>
> I thought extras were supported since they come stock with the Klipper installation, guess I was wrong; as I said, I’ve only ever used Klipper, never developed for it.

While they do work well and are quite powerful, they will make your Klipper installation appear “dirty” which will make it harder to get support.

> [@The "dirty" Flag and the Team's Position](https://klipper.discourse.group/t/the-dirty-flag-and-the-teams-position/22753):
>
> Background Klipper’s main-line code is [published on GitHub](https://github.com/Klipper3d/klipper). Upon start, Klipper checks if the locally installed code is the same as the code published in this official repository. If not, the code is marked as dirty, and a respective notification is placed in the klippy.log. This warning can look like: Git version: 'v0.12.0-439-g1fc6d214-dirty' Untracked files: klippy/extras/autotune\_tmc.py, klippy/extras/gcode\_shell\_command.py, klippy/extras/motor\_constants.py Modified files: klippy/chelper/s…
