FastAPI requests to internal endpoint

See original GitHub issue

I was working on a project recently and was experiencing problems with FastAPI interacting with the requests library. The goal I’m trying to achieve is to have a health_status endpoint function hit the health version endpoint as well. I have recreated the problem with 2 smaller projects, a simple fastapi and a simple flask. Flask is able to achieve the goal, but Fastapi freezes up when trying to do it.

Here is the code using flask. When hitting the “/health/status” endpoin it should return {“message”: “Hello World”} however it freezes up the entire api. It doesn’t even allow me to hit the root endpoint afterwards unless I rerun the program. However, I am able to hit the root endpoint if I hit it before calling “/health/status."

Code

import uvicorn
from fastapi import FastAPI, Request
import requests

app = FastAPI(debug=True)


@app.get("/")
async def root():
    return {"message": "Hello World"}


@app.get("/health/status")
async def health():
    resp = requests.get(url="http://127.0.0.1:8000/")
    return resp.text


if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)

Similarly, the code using flask is listed below. This works just fine, where if I hit “/health/status” then it will return “Hello World”

from flask import Flask
import requests

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World'


@app.route('/health/status')
def health_status():
    resp = requests.get(url="http://127.0.0.1:5000/")
    return resp.text


if __name__ == '__main__':
    app.run()

Description

As mentioned above, instead of returning “Hello World” like it should, it just ties up the whole api when using FastAPI.

Environment

  • OS: [e.g. Linux / Windows / macOS]: Windows
  • FastAPI Version [e.g. 0.3.0]: “==0.63.0”
  • Python version: “==3.6.8”

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
ArcLightSlavikcommented, Jan 5, 2021

Use httpx instead of requests, would make your call asynchronous and stop the blocking.

async with httpx.AsyncClient() as client:
    resp = await client.get(url="http://127.0.0.1:8000/")
1reaction
Kludexcommented, Jan 5, 2021

The thing is that you’re calling a blocking synchronous function on a coroutine and it will block the event loop. Possible solutions are:

  1. Make health() synchronous i.e. remove the async. This way it will run in another thread.
  2. Use the @ArcLightSlavik approach, meaning that you await for the response. In other words, you give time on the event loop to other functions (root() in this case).

Approach 2 performs better.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using the Request Directly - FastAPI
Use the Request object directly​​ For that you need to access the request directly. By declaring a path operation function parameter with the...
Read more >
Custom Request and APIRoute class - FastAPI
And an APIRoute subclass to use that custom request class. ... But this example is still valid and it shows how to interact...
Read more >
OpenAPI Callbacks - FastAPI
The process that happens when your API app calls the external API is named a "callback". Because the software that the external developer...
Read more >
Bigger Applications - Multiple Files - FastAPI
If you are building an application or a web API, it's rarely the case that you can put everything on a single file....
Read more >
Request Body - FastAPI
Request body + path + query parameters¶ ... You can also declare body, path and query parameters, all at the same time. FastAPI...
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