Ask
167
@first_repo_finn ·

Polling an API every 30 seconds with time.sleep in a while True — is that acceptable or is there a proper way?

It runs all day on my laptop, prints a line when something changes, and occasionally it just stops doing anything without an error until I kill it and restart. Ctrl+C also produces an ugly traceback which makes me think I am doing that part wrong too. This is my first script that is meant to run for hours rather than seconds, so I do not know which of my instincts here are wrong.

7 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @pinned_versions · 3mo ago · 2 replies

    Two things that make a long-running loop behave itself. Catch KeyboardInterrupt around the loop and exit cleanly so Ctrl+C prints one tidy line instead of a traceback. And back off when the endpoint complains: if you get a rate limit response, sleep longer before retrying rather than hammering it every thirty seconds, and respect the header that tells you how long to wait if the API sends one. Polite polling is also what keeps your key from being blocked.

    168
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @csv_apologist · 3mo ago

      Exponential backoff sounds fancy but it is four lines. Double the wait on each consecutive failure, cap it, reset on success.

      62
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @chalkbag_chen · 3mo ago · 3 replies

    The hang is almost certainly not the sleep, it is the request. If you call an HTTP library without passing a timeout, the default behaviour on many of them is to wait indefinitely, so one connection that never answers parks your script forever with no error and no output. Pass an explicit timeout on every request and the symptom you describe usually disappears. Everything else in your setup is fine for a script of this size.

    203
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @four_percent_fi · 3mo ago

      Then that is your bug. Add the timeout, and wrap the call so a timeout logs a line and continues to the next cycle instead of ending the loop.

      78
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @first_repo_finn · 3mo ago

      I do not pass a timeout anywhere. That maps exactly onto the behaviour — it stops with no error and no CPU use.

      71
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @row_level_sam · 3mo ago

    Sleeping thirty seconds after the work means your interval is thirty seconds plus however long the request took, so the schedule drifts. If you care about hitting a steady cadence, record the time before you start the cycle and sleep for whatever is left of the thirty seconds afterward, floored at zero. For a personal script the drift rarely matters; for anything logging on a timeline it matters a lot.

    154
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @xlookup_lena · 2h ago

    You do not need async for one endpoint every thirty seconds, whatever the internet tells you. A sleep loop with a timeout and a try/except is the correct size of solution here.

    1
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report