The curl -I option (which is used in the example you provided) is the same as using curl --head and performrs an HTTP HEAD request, in order to fetch the headers only (not the body/content of the resource):
The HTTP HEAD method requests the headers that would be
returned if the HEAD request's URL was instead requested with the
HTTP GET method. For example, if a URL might produce a large
download, a HEAD request could read its Content-Length header
to check the filesize without actually downloading the file.
The requested resource/endpoint you are trying to call supports only GET requests; hence, the 405 Method Not Allowed response status code, which indicates that the server knows the request method, but the target resource doesn't support this method.
To demonstrate this, have a look at the example below:
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
async def main():
return {'Hello': 'World'}
Test using Python requests (similar result is obtained using curl -I http://127.0.0.1:8000)
import requests
# Making a GET request
# r = requests.get('http://127.0.0.1:8000')
# Making a HEAD request
r = requests.head('http://127.0.0.1:8000')
# check status code for response received
print(r.status_code, r.reason)
# print headers of request
print(r.headers)
# checking if request contains any content
print(r.content)
Output (indicating by the allow response header which request methods are supported by the requested resource):
405 Method Not Allowed
{'date': 'Sun, 12 Mar 2023', 'server': 'uvicorn', 'allow': 'GET', 'content-length': '31', 'content-type': 'application/json'}
b''
If, instead, you performed a GET request (in order to issue a GET request in the example above, uncomment the line for GET request and comment the one for HEAD request, or in curl use curl http://127.0.0.1:8000), the response would be as follows:
200 OK
{'date': 'Sun, 12 Mar 2023', 'server': 'uvicorn', 'content-length': '17', 'content-type': 'application/json'}
b'{"Hello":"World"}'
Solutions
To make a FastAPI endpoint supporting more than one HTTP request methods (e.g., both GET and HEAD requests), the following solutions are available.
Solution 1
Add a decorator for each request method that you would like the endpoint to support. For instance:
from fastapi import FastAPI
app = FastAPI()
@app.head('/')
@app.get('/')
async def main():
return {'Hello': 'World'}
Solution 2
Use the @app.api_route() decorator, which allows you to define the set of supported request methods for the endpoint. For example:
from fastapi import FastAPI
app = FastAPI()
@app.api_route('/', methods=['GET', 'HEAD'])
async def main():
return {'Hello': 'World'}
Output
Both solutions above would respond as follows (when a HEAD request is issued by a client):
200 OK
{'date': 'Sun, 12 Mar 2023', 'server': 'uvicorn', 'content-length': '17', 'content-type': 'application/json'}
b''
Note that 405 Method Not Allowed response may also be caused by other reasons—see related answers here and here, as well as here and here.