_status_codes.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from __future__ import annotations
  2. from enum import IntEnum
  3. __all__ = ["codes"]
  4. class codes(IntEnum):
  5. """HTTP status codes and reason phrases
  6. Status codes from the following RFCs are all observed:
  7. * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616
  8. * RFC 6585: Additional HTTP Status Codes
  9. * RFC 3229: Delta encoding in HTTP
  10. * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518
  11. * RFC 5842: Binding Extensions to WebDAV
  12. * RFC 7238: Permanent Redirect
  13. * RFC 2295: Transparent Content Negotiation in HTTP
  14. * RFC 2774: An HTTP Extension Framework
  15. * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2)
  16. * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)
  17. * RFC 7725: An HTTP Status Code to Report Legal Obstacles
  18. * RFC 8297: An HTTP Status Code for Indicating Hints
  19. * RFC 8470: Using Early Data in HTTP
  20. """
  21. def __new__(cls, value: int, phrase: str = "") -> codes:
  22. obj = int.__new__(cls, value)
  23. obj._value_ = value
  24. obj.phrase = phrase # type: ignore[attr-defined]
  25. return obj
  26. def __str__(self) -> str:
  27. return str(self.value)
  28. @classmethod
  29. def get_reason_phrase(cls, value: int) -> str:
  30. try:
  31. return codes(value).phrase # type: ignore
  32. except ValueError:
  33. return ""
  34. @classmethod
  35. def is_informational(cls, value: int) -> bool:
  36. """
  37. Returns `True` for 1xx status codes, `False` otherwise.
  38. """
  39. return 100 <= value <= 199
  40. @classmethod
  41. def is_success(cls, value: int) -> bool:
  42. """
  43. Returns `True` for 2xx status codes, `False` otherwise.
  44. """
  45. return 200 <= value <= 299
  46. @classmethod
  47. def is_redirect(cls, value: int) -> bool:
  48. """
  49. Returns `True` for 3xx status codes, `False` otherwise.
  50. """
  51. return 300 <= value <= 399
  52. @classmethod
  53. def is_client_error(cls, value: int) -> bool:
  54. """
  55. Returns `True` for 4xx status codes, `False` otherwise.
  56. """
  57. return 400 <= value <= 499
  58. @classmethod
  59. def is_server_error(cls, value: int) -> bool:
  60. """
  61. Returns `True` for 5xx status codes, `False` otherwise.
  62. """
  63. return 500 <= value <= 599
  64. @classmethod
  65. def is_error(cls, value: int) -> bool:
  66. """
  67. Returns `True` for 4xx or 5xx status codes, `False` otherwise.
  68. """
  69. return 400 <= value <= 599
  70. # informational
  71. CONTINUE = 100, "Continue"
  72. SWITCHING_PROTOCOLS = 101, "Switching Protocols"
  73. PROCESSING = 102, "Processing"
  74. EARLY_HINTS = 103, "Early Hints"
  75. # success
  76. OK = 200, "OK"
  77. CREATED = 201, "Created"
  78. ACCEPTED = 202, "Accepted"
  79. NON_AUTHORITATIVE_INFORMATION = 203, "Non-Authoritative Information"
  80. NO_CONTENT = 204, "No Content"
  81. RESET_CONTENT = 205, "Reset Content"
  82. PARTIAL_CONTENT = 206, "Partial Content"
  83. MULTI_STATUS = 207, "Multi-Status"
  84. ALREADY_REPORTED = 208, "Already Reported"
  85. IM_USED = 226, "IM Used"
  86. # redirection
  87. MULTIPLE_CHOICES = 300, "Multiple Choices"
  88. MOVED_PERMANENTLY = 301, "Moved Permanently"
  89. FOUND = 302, "Found"
  90. SEE_OTHER = 303, "See Other"
  91. NOT_MODIFIED = 304, "Not Modified"
  92. USE_PROXY = 305, "Use Proxy"
  93. TEMPORARY_REDIRECT = 307, "Temporary Redirect"
  94. PERMANENT_REDIRECT = 308, "Permanent Redirect"
  95. # client error
  96. BAD_REQUEST = 400, "Bad Request"
  97. UNAUTHORIZED = 401, "Unauthorized"
  98. PAYMENT_REQUIRED = 402, "Payment Required"
  99. FORBIDDEN = 403, "Forbidden"
  100. NOT_FOUND = 404, "Not Found"
  101. METHOD_NOT_ALLOWED = 405, "Method Not Allowed"
  102. NOT_ACCEPTABLE = 406, "Not Acceptable"
  103. PROXY_AUTHENTICATION_REQUIRED = 407, "Proxy Authentication Required"
  104. REQUEST_TIMEOUT = 408, "Request Timeout"
  105. CONFLICT = 409, "Conflict"
  106. GONE = 410, "Gone"
  107. LENGTH_REQUIRED = 411, "Length Required"
  108. PRECONDITION_FAILED = 412, "Precondition Failed"
  109. REQUEST_ENTITY_TOO_LARGE = 413, "Request Entity Too Large"
  110. REQUEST_URI_TOO_LONG = 414, "Request-URI Too Long"
  111. UNSUPPORTED_MEDIA_TYPE = 415, "Unsupported Media Type"
  112. REQUESTED_RANGE_NOT_SATISFIABLE = 416, "Requested Range Not Satisfiable"
  113. EXPECTATION_FAILED = 417, "Expectation Failed"
  114. IM_A_TEAPOT = 418, "I'm a teapot"
  115. MISDIRECTED_REQUEST = 421, "Misdirected Request"
  116. UNPROCESSABLE_ENTITY = 422, "Unprocessable Entity"
  117. LOCKED = 423, "Locked"
  118. FAILED_DEPENDENCY = 424, "Failed Dependency"
  119. TOO_EARLY = 425, "Too Early"
  120. UPGRADE_REQUIRED = 426, "Upgrade Required"
  121. PRECONDITION_REQUIRED = 428, "Precondition Required"
  122. TOO_MANY_REQUESTS = 429, "Too Many Requests"
  123. REQUEST_HEADER_FIELDS_TOO_LARGE = 431, "Request Header Fields Too Large"
  124. UNAVAILABLE_FOR_LEGAL_REASONS = 451, "Unavailable For Legal Reasons"
  125. # server errors
  126. INTERNAL_SERVER_ERROR = 500, "Internal Server Error"
  127. NOT_IMPLEMENTED = 501, "Not Implemented"
  128. BAD_GATEWAY = 502, "Bad Gateway"
  129. SERVICE_UNAVAILABLE = 503, "Service Unavailable"
  130. GATEWAY_TIMEOUT = 504, "Gateway Timeout"
  131. HTTP_VERSION_NOT_SUPPORTED = 505, "HTTP Version Not Supported"
  132. VARIANT_ALSO_NEGOTIATES = 506, "Variant Also Negotiates"
  133. INSUFFICIENT_STORAGE = 507, "Insufficient Storage"
  134. LOOP_DETECTED = 508, "Loop Detected"
  135. NOT_EXTENDED = 510, "Not Extended"
  136. NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required"
  137. # Include lower-case styles for `requests` compatibility.
  138. for code in codes:
  139. setattr(codes, code._name_.lower(), int(code))