Browse Source

Add support for Python's http.HTTPStatus in status_code (#1534)

* Normalise IntEnums to ints for route status codes

Closes #1349

* add tests for status code enum support

* add docs for status code enum support

* add endpoint test for enum status code

* 📝 Update note about http.HTTPStatus

Co-authored-by: Sebastián Ramírez <[email protected]>
pull/1576/head
retnikt 5 years ago
committed by GitHub
parent
commit
c6dd627bdd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      docs/en/docs/tutorial/response-status-code.md
  2. 4
      fastapi/routing.py
  3. 7
      tests/main.py
  4. 18
      tests/test_application.py

3
docs/en/docs/tutorial/response-status-code.md

@ -17,6 +17,9 @@ The same way you can specify a response model, you can also declare the HTTP sta
The `status_code` parameter receives a number with the HTTP status code. The `status_code` parameter receives a number with the HTTP status code.
!!! info
`status_code` can alternatively also receive an `IntEnum`, such as Python's <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>.
It will: It will:
* Return that status code in the response. * Return that status code in the response.

4
fastapi/routing.py

@ -1,4 +1,5 @@
import asyncio import asyncio
import enum
import inspect import inspect
import json import json
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Type, Union from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Type, Union
@ -296,6 +297,9 @@ class APIRoute(routing.Route):
dependency_overrides_provider: Any = None, dependency_overrides_provider: Any = None,
callbacks: Optional[List["APIRoute"]] = None, callbacks: Optional[List["APIRoute"]] = None,
) -> None: ) -> None:
# normalise enums e.g. http.HTTPStatus
if isinstance(status_code, enum.IntEnum):
status_code = int(status_code)
self.path = path self.path = path
self.endpoint = endpoint self.endpoint = endpoint
self.name = get_name(endpoint) if name is None else name self.name = get_name(endpoint) if name is None else name

7
tests/main.py

@ -1,3 +1,5 @@
import http
from fastapi import FastAPI, Path, Query from fastapi import FastAPI, Path, Query
app = FastAPI() app = FastAPI()
@ -184,3 +186,8 @@ def get_query_param_required(query=Query(...)):
@app.get("/query/param-required/int") @app.get("/query/param-required/int")
def get_query_param_required_type(query: int = Query(...)): def get_query_param_required_type(query: int = Query(...)):
return f"foo bar {query}" return f"foo bar {query}"
@app.get("/enum-status-code", status_code=http.HTTPStatus.CREATED)
def get_enum_status_code():
return "foo bar"

18
tests/test_application.py

@ -1078,6 +1078,18 @@ openapi_schema = {
], ],
} }
}, },
"/enum-status-code": {
"get": {
"responses": {
"201": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
},
"summary": "Get Enum Status Code",
"operationId": "get_enum_status_code_enum_status_code_get",
}
},
}, },
"components": { "components": {
"schemas": { "schemas": {
@ -1149,3 +1161,9 @@ def test_redoc():
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8" assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "redoc@next" in response.text assert "redoc@next" in response.text
def test_enum_status_code_response():
response = client.get("/enum-status-code")
assert response.status_code == 201, response.text
assert response.json() == "foo bar"

Loading…
Cancel
Save