Browse Source

Auto-add HEAD method for GET routes (issue #1773)

- When GET is in route methods, automatically add HEAD to the methods set
- Mirrors Starlette behavior (starlette/routing.py line 243-244)
- 2-line change in APIRoute.__init__ (fastapi/routing.py)
- 4 new tests covering: basic HEAD, parameterized paths, no HEAD for POST, empty body

Fixes #1773
pull/15359/head
Thor Agent 3 months ago
parent
commit
62b1f70ad5
  1. 2
      fastapi/routing.py
  2. 57
      tests/test_auto_head.py

2
fastapi/routing.py

@ -890,6 +890,8 @@ class APIRoute(routing.Route):
if methods is None:
methods = ["GET"]
self.methods: set[str] = {method.upper() for method in methods}
if "GET" in self.methods:
self.methods.add("HEAD")
if isinstance(generate_unique_id_function, DefaultPlaceholder):
current_generate_unique_id: Callable[[APIRoute], str] = (
generate_unique_id_function.value

57
tests/test_auto_head.py

@ -0,0 +1,57 @@
"""Test that HEAD requests are automatically supported for GET routes (issue #1773)."""
from fastapi import FastAPI
from fastapi.testclient import TestClient
def test_head_for_get_route():
"""HEAD request on a GET route should return 200, not 405."""
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
client = TestClient(app)
response = client.head("/")
assert response.status_code == 200
assert response.headers.get("content-type") is not None
def test_head_for_get_route_with_path():
"""HEAD request on a parameterized GET route should work."""
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
client = TestClient(app)
response = client.head("/items/42")
assert response.status_code == 200
def test_head_not_auto_added_for_post():
"""POST routes should NOT automatically support HEAD."""
app = FastAPI()
@app.post("/items/")
def create_item():
return {"created": True}
client = TestClient(app)
response = client.head("/items/")
assert response.status_code == 405
def test_head_response_has_no_body():
"""HEAD response should have no body content."""
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
client = TestClient(app)
response = client.head("/")
assert response.status_code == 200
assert response.content == b""
Loading…
Cancel
Save