question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] How does one setup a global timeout to all requests?

See original GitHub issue

First check

Ticked all checks, then first commitment choice
  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google “How to X in FastAPI” and didn’t find any information.
  • I already read and followed all the tutorial in the docs and didn’t find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to one of:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • I already hit the “watch” button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Description

Hi there, first of all many thanks for the work on FastAPI - this is now my goto framework for building Python-based REST APIs 😃

My question is about adding a global timeout to any potential request served by the server. My use-case includes occasionally long loading times when I have to load a new model for a given user request, and instead of blocking for 30-50s (which would often timeout on the user side due to default connection timeouts), I would like to return a temporary error whenever any endpoint takes more than a given delay to complete.

Example

Today the only way I found to implement a timeout on every request is to wrap every endpoint method within a context manager like this one:

@contextmanager
def timeout_after(seconds: int):
    # Register a function to raise a TimeoutError on the signal.
    signal.signal(signal.SIGALRM, raise_timeout)
    # Schedule the signal to be sent after `seconds`.
    signal.alarm(seconds)

    try:
        yield
    finally:
        # Unregister the signal so it won't be triggered if the timeout is not reached.
        signal.signal(signal.SIGALRM, signal.SIG_IGN)

def raise_timeout(_, frame):
    raise TimeoutError

# Used as such:
@timeout_after(5)
@app.get("/1/version", tags=["Meta"],
         description="Check if the server is alive, returning the version it runs.",
         response_model=Version,
         response_description="the version of the API currently running.")
async def version() -> Version:
    return current_version

This is however quite cumbersome to add on every single function decorated as an endpoint. Besides, it feels hacky: isn’t there a better way to define app-level timeouts broadly, with a common handler, maybe akin to how ValidationErrors can be managed in a single global handler?

Environment

  • OS: [e.g. Linux / Windows / macOS]: Linux
  • FastAPI Version [e.g. 0.3.0]: 0.58.0
  • Python version: 3.7.7

Additional context

I looked into Starlette’s timeout support to see if that was handled at a lower level. but to no avail.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:7
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

12reactions
MasterScratcommented, Nov 8, 2021

This is good to return an error message to the user in case of timeout, but is there a way to actually kill the request at the same time so it doesn’t keep using resources?

10reactions
PLNechcommented, Sep 17, 2020

@thomas-maschler: thanks for the advice. Unfortunately I’ve tried using Gunicorn’s timeout, but it triggers a full restart of the app, disrupting other users of the service (e.g. by unloading their models from memory). What I’m trying to achieve is rather to enforce a timeout on individual requests, without affecting any other work handled by this worker.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a way to globally override requests' timeout setting?
The simplest way is to "shim" the session's request function: import requests import functools s = requests.
Read more >
How to change the timeout of an HTTP request at the API level ...
Default : 30 seconds. This is a global property that applies to the endpoints of all APIs. If you prefer to specify a...
Read more >
Setting a Request Timeout for a Spring REST API - Baeldung
It has a timeout property that we can set. The default value for this property is -1, which is equivalent to not having...
Read more >
A Complete Guide to Timeouts in Node.js - Better Stack
Setting timeouts on outgoing network requests is a crucial requirement that must not be overlooked. Networks are unreliable, and third-party ...
Read more >
Setting request timeout (services) | Cloud Run Documentation
For Cloud Run services, the request timeout setting specifies the time within which a response must be returned by services deployed to Cloud...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found