Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion fasthttp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import status
from .__meta__ import __version__
from .app import FastHTTP
from .dependencies import Depends
Expand All @@ -11,5 +12,6 @@
"FastHTTP",
"MiddlewareManager",
"Router",
"__version__"
"__version__",
"status",
)
18 changes: 9 additions & 9 deletions fasthttp/openapi/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from annotated_doc import Doc

from fasthttp.response import Response

from fasthttp import status
from .generator import generate_openapi_schema
from .swagger import get_swagger_html, get_not_found_html
from .urls import build_docs_urls
Expand Down Expand Up @@ -38,7 +38,7 @@ async def handle_docs(
request_url=urls["request_url"],
)
return Response(
status=200,
status=status.HTTP_200_OK,
text=html,
headers={"Content-Type": "text/html"},
)
Expand All @@ -64,7 +64,7 @@ async def handle_openapi_json(
schema = generate_openapi_schema(app, server_url=urls["request_url"])
json_str = json.dumps(schema, indent=2, ensure_ascii=False)
return Response(
status=200,
status=status.HTTP_200_OK,
text=json_str,
headers={"Content-Type": "application/json"},
)
Expand Down Expand Up @@ -92,7 +92,7 @@ async def handle_not_found(
openapi_url=urls["openapi_url"],
)
return Response(
status=404,
status=status.HTTP_404_NOT_FOUND,
text=html,
headers={"Content-Type": "text/html"},
)
Expand Down Expand Up @@ -127,7 +127,7 @@ async def handle_request(

if not url:
return Response(
status=400,
status=status.HTTP_400_BAD_REQUEST,
text=json.dumps({"error": "URL is required"}),
headers={"Content-Type": "application/json"},
)
Expand Down Expand Up @@ -160,26 +160,26 @@ async def handle_request(
pass

return Response(
status=200,
status=status.HTTP_200_OK,
text=json.dumps(result, indent=2, ensure_ascii=False),
headers={"Content-Type": "application/json"},
)

except httpx.ConnectError as e:
return Response(
status=502,
status=status.HTTP_502_BAD_GATEWAY,
text=json.dumps({"error": f"Connection error: {str(e)}"}),
headers={"Content-Type": "application/json"},
)
except httpx.TimeoutException as e:
return Response(
status=504,
status=status.HTTP_504_GATEWAY_TIMEOUT,
text=json.dumps({"error": f"Timeout: {str(e)}"}),
headers={"Content-Type": "application/json"},
)
except Exception as e:
return Response(
status=500,
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
text=json.dumps({"error": f"Request failed: {str(e)}"}),
headers={"Content-Type": "application/json"},
)
177 changes: 177 additions & 0 deletions fasthttp/status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
"""
HTTP Status Codes
Based on IANA + RFC 9110
"""

from __future__ import annotations

import warnings

__all__ = [
# 1xx
"HTTP_100_CONTINUE",
"HTTP_101_SWITCHING_PROTOCOLS",
"HTTP_102_PROCESSING",
"HTTP_103_EARLY_HINTS",

# 2xx
"HTTP_200_OK",
"HTTP_201_CREATED",
"HTTP_202_ACCEPTED",
"HTTP_203_NON_AUTHORITATIVE_INFORMATION",
"HTTP_204_NO_CONTENT",
"HTTP_205_RESET_CONTENT",
"HTTP_206_PARTIAL_CONTENT",
"HTTP_207_MULTI_STATUS",
"HTTP_208_ALREADY_REPORTED",
"HTTP_226_IM_USED",

# 3xx
"HTTP_300_MULTIPLE_CHOICES",
"HTTP_301_MOVED_PERMANENTLY",
"HTTP_302_FOUND",
"HTTP_303_SEE_OTHER",
"HTTP_304_NOT_MODIFIED",
"HTTP_307_TEMPORARY_REDIRECT",
"HTTP_308_PERMANENT_REDIRECT",

# 4xx
"HTTP_400_BAD_REQUEST",
"HTTP_401_UNAUTHORIZED",
"HTTP_402_PAYMENT_REQUIRED",
"HTTP_403_FORBIDDEN",
"HTTP_404_NOT_FOUND",
"HTTP_405_METHOD_NOT_ALLOWED",
"HTTP_406_NOT_ACCEPTABLE",
"HTTP_407_PROXY_AUTHENTICATION_REQUIRED",
"HTTP_408_REQUEST_TIMEOUT",
"HTTP_409_CONFLICT",
"HTTP_410_GONE",
"HTTP_411_LENGTH_REQUIRED",
"HTTP_412_PRECONDITION_FAILED",
"HTTP_413_CONTENT_TOO_LARGE",
"HTTP_414_URI_TOO_LONG",
"HTTP_415_UNSUPPORTED_MEDIA_TYPE",
"HTTP_416_RANGE_NOT_SATISFIABLE",
"HTTP_417_EXPECTATION_FAILED",
"HTTP_418_IM_A_TEAPOT",
"HTTP_421_MISDIRECTED_REQUEST",
"HTTP_422_UNPROCESSABLE_CONTENT",
"HTTP_423_LOCKED",
"HTTP_424_FAILED_DEPENDENCY",
"HTTP_425_TOO_EARLY",
"HTTP_426_UPGRADE_REQUIRED",
"HTTP_428_PRECONDITION_REQUIRED",
"HTTP_429_TOO_MANY_REQUESTS",
"HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE",
"HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS",

# 5xx
"HTTP_500_INTERNAL_SERVER_ERROR",
"HTTP_501_NOT_IMPLEMENTED",
"HTTP_502_BAD_GATEWAY",
"HTTP_503_SERVICE_UNAVAILABLE",
"HTTP_504_GATEWAY_TIMEOUT",
"HTTP_505_HTTP_VERSION_NOT_SUPPORTED",
"HTTP_506_VARIANT_ALSO_NEGOTIATES",
"HTTP_507_INSUFFICIENT_STORAGE",
"HTTP_508_LOOP_DETECTED",
"HTTP_510_NOT_EXTENDED",
"HTTP_511_NETWORK_AUTHENTICATION_REQUIRED",
]

# 1xx
HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
HTTP_102_PROCESSING = 102
HTTP_103_EARLY_HINTS = 103

# 2xx
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_207_MULTI_STATUS = 207
HTTP_208_ALREADY_REPORTED = 208
HTTP_226_IM_USED = 226

# 3xx
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_308_PERMANENT_REDIRECT = 308

# 4xx
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_CONTENT_TOO_LARGE = 413
HTTP_414_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_418_IM_A_TEAPOT = 418
HTTP_421_MISDIRECTED_REQUEST = 421
HTTP_422_UNPROCESSABLE_CONTENT = 422
HTTP_423_LOCKED = 423
HTTP_424_FAILED_DEPENDENCY = 424
HTTP_425_TOO_EARLY = 425
HTTP_426_UPGRADE_REQUIRED = 426
HTTP_428_PRECONDITION_REQUIRED = 428
HTTP_429_TOO_MANY_REQUESTS = 429
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451

# 5xx
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
HTTP_507_INSUFFICIENT_STORAGE = 507
HTTP_508_LOOP_DETECTED = 508
HTTP_510_NOT_EXTENDED = 510
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511


# deprecated aliases
__deprecated__ = {
"HTTP_413_REQUEST_ENTITY_TOO_LARGE": 413,
"HTTP_414_REQUEST_URI_TOO_LONG": 414,
"HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE": 416,
"HTTP_422_UNPROCESSABLE_ENTITY": 422,
}


def __getattr__(name: str) -> int:
if name in __deprecated__:
warnings.warn(
f"{name} is deprecated",
DeprecationWarning,
stacklevel=2,
)
return __deprecated__[name]

raise AttributeError(f"module 'fasthttp.status' has no attribute '{name}'")


def __dir__() -> list:
return sorted(list(__all__) + list(__deprecated__.keys()))
Loading