Skip to content

Commit

Permalink
Release 22.6 (#2487)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins committed Jun 28, 2022
1 parent aba333b commit 13d5a44
Show file tree
Hide file tree
Showing 22 changed files with 156 additions and 372 deletions.
14 changes: 8 additions & 6 deletions CHANGELOG.rst
Expand Up @@ -313,8 +313,10 @@ Version 21.3.0
`#2074 <https://github.com/sanic-org/sanic/pull/2074>`_
Performance adjustments in ``handle_request_``

Version 20.12.3
---------------
Version 20.12.3 🔷
------------------

`Current LTS version`

**Bugfixes**

Expand Down Expand Up @@ -348,17 +350,17 @@ Version 19.12.5
`#2027 <https://github.com/sanic-org/sanic/pull/2027>`_
Remove old chardet requirement, add in hard multidict requirement

Version 20.12.0
---------------
Version 20.12.0 🔹
-----------------

**Features**

*
`#1993 <https://github.com/sanic-org/sanic/pull/1993>`_
Add disable app registry

Version 20.12.0
---------------
Version 20.12.0 🔹
-----------------

**Features**

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Expand Up @@ -9,7 +9,7 @@ API
===

.. toctree::
:maxdepth: 2
:maxdepth: 3

👥 User Guide <https://sanicframework.org/guide/>
sanic/api_reference
Expand Down
1 change: 1 addition & 0 deletions docs/sanic/changelog.rst
@@ -1,6 +1,7 @@
📜 Changelog
============

.. mdinclude:: ./releases/22/22.6.md
.. mdinclude:: ./releases/22/22.3.md
.. mdinclude:: ./releases/21/21.12.md
.. mdinclude:: ./releases/21/21.9.md
Expand Down
6 changes: 4 additions & 2 deletions docs/sanic/releases/21/21.12.md
@@ -1,10 +1,12 @@
## Version 21.12.1
## Version 21.12.1 🔷

_Current LTS version_

- [#2349](https://github.com/sanic-org/sanic/pull/2349) Only display MOTD on startup
- [#2354](https://github.com/sanic-org/sanic/pull/2354) Ignore name argument in Python 3.7
- [#2355](https://github.com/sanic-org/sanic/pull/2355) Add config.update support for all config values

## Version 21.12.0
## Version 21.12.0 🔹

### Features
- [#2260](https://github.com/sanic-org/sanic/pull/2260) Allow early Blueprint registrations to still apply later added objects
Expand Down
42 changes: 42 additions & 0 deletions docs/sanic/releases/22/22.6.md
@@ -0,0 +1,42 @@
## Version 22.6.0 🔶

_Current version_

### Features
- [#2378](https://github.com/sanic-org/sanic/pull/2378) Introduce HTTP/3 and autogeneration of TLS certificates in `DEBUG` mode
- 👶 *EARLY RELEASE FEATURE*: Serving Sanic over HTTP/3 is an early release feature. It does not yet fully cover the HTTP/3 spec, but instead aims for feature parity with Sanic's existing HTTP/1.1 server. Websockets, WebTransport, push responses are examples of some features not yet implemented.
- 📦 *EXTRA REQUIREMENT*: Not all HTTP clients are capable of interfacing with HTTP/3 servers. You may need to install a [HTTP/3 capable client](https://curl.se/docs/http3.html).
- 📦 *EXTRA REQUIREMENT*: In order to use TLS autogeneration, you must install either [mkcert](https://github.com/FiloSottile/mkcert) or [trustme](https://github.com/python-trio/trustme).
- [#2416](https://github.com/sanic-org/sanic/pull/2416) Add message to `task.cancel`
- [#2420](https://github.com/sanic-org/sanic/pull/2420) Add exception aliases for more consistent naming with standard HTTP response types (`BadRequest`, `MethodNotAllowed`, `RangeNotSatisfiable`)
- [#2432](https://github.com/sanic-org/sanic/pull/2432) Expose ASGI `scope` as a property on the `Request` object
- [#2438](https://github.com/sanic-org/sanic/pull/2438) Easier access to websocket class for annotation: `from sanic import Websocket`
- [#2439](https://github.com/sanic-org/sanic/pull/2439) New API for reading form values with options: `Request.get_form`
- [#2447](https://github.com/sanic-org/sanic/pull/2447), [#2486](https://github.com/sanic-org/sanic/pull/2486) Improved API to support setting cache control headers
- [#2453](https://github.com/sanic-org/sanic/pull/2453) Move verbosity filtering to logger
- [#2475](https://github.com/sanic-org/sanic/pull/2475) Expose getter for current request using `Request.get_current()`

### Bugfixes
- [#2448](https://github.com/sanic-org/sanic/pull/2448) Fix to allow running with `pythonw.exe` or places where there is no `sys.stdout`
- [#2451](https://github.com/sanic-org/sanic/pull/2451) Trigger `http.lifecycle.request` signal in ASGI mode
- [#2455](https://github.com/sanic-org/sanic/pull/2455) Resolve typing of stacked route definitions
- [#2463](https://github.com/sanic-org/sanic/pull/2463) Properly catch websocket CancelledError in websocket handler in Python 3.7

### Deprecations and Removals
- [#2487](https://github.com/sanic-org/sanic/pull/2487) v22.6 deprecations and changes
1. Optional application registry
1. Execution of custom handlers after some part of response was sent
1. Configuring fallback handlers on the `ErrorHandler`
1. Custom `LOGO` setting
1. `sanic.response.stream`
1. `AsyncioServer.init`

### Developer infrastructure
- [#2449](https://github.com/sanic-org/sanic/pull/2449) Clean up `black` and `isort` config
- [#2479](https://github.com/sanic-org/sanic/pull/2479) Fix some flappy tests

### Improved Documentation
- [#2461](https://github.com/sanic-org/sanic/pull/2461) Update example to match current application naming standards
- [#2466](https://github.com/sanic-org/sanic/pull/2466) Better type annotation for `Extend`
- [#2485](https://github.com/sanic-org/sanic/pull/2485) Improved help messages in CLI

2 changes: 1 addition & 1 deletion sanic/__version__.py
@@ -1 +1 @@
__version__ = "22.3.2"
__version__ = "22.6.0"
40 changes: 7 additions & 33 deletions sanic/app.py
Expand Up @@ -169,7 +169,6 @@ def __init__(
strict_slashes: bool = False,
log_config: Optional[Dict[str, Any]] = None,
configure_logging: bool = True,
register: Optional[bool] = None,
dumps: Optional[Callable[..., AnyStr]] = None,
) -> None:
super().__init__(name=name)
Expand Down Expand Up @@ -218,20 +217,9 @@ def __init__(

# Register alternative method names
self.go_fast = self.run

if register is not None:
deprecation(
"The register argument is deprecated and will stop working "
"in v22.6. After v22.6 all apps will be added to the Sanic "
"app registry.",
22.6,
)
self.config.REGISTER = register
if self.config.REGISTER:
self.__class__.register_app(self)

self.router.ctx.app = self
self.signal_router.ctx.app = self
self.__class__.register_app(self)

if dumps:
BaseHTTPResponse._dumps = dumps # type: ignore
Expand Down Expand Up @@ -736,37 +724,24 @@ async def handle_exception(
"has at least partially been sent."
)

# ----------------- deprecated -----------------
handler = self.error_handler._lookup(
exception, request.name if request else None
)
if handler:
deprecation(
logger.warning(
"An error occurred while handling the request after at "
"least some part of the response was sent to the client. "
"Therefore, the response from your custom exception "
f"handler {handler.__name__} will not be sent to the "
"client. Beginning in v22.6, Sanic will stop executing "
"custom exception handlers in this scenario. Exception "
"handlers should only be used to generate the exception "
"responses. If you would like to perform any other "
"action on a raised exception, please consider using a "
"The response from your custom exception handler "
f"{handler.__name__} will not be sent to the client."
"Exception handlers should only be used to generate the "
"exception responses. If you would like to perform any "
"other action on a raised exception, consider using a "
"signal handler like "
'`@app.signal("http.lifecycle.exception")`\n'
"For further information, please see the docs: "
"https://sanicframework.org/en/guide/advanced/"
"signals.html",
22.6,
)
try:
response = self.error_handler.response(request, exception)
if isawaitable(response):
response = await response
except BaseException as e:
logger.error("An error occurred in the exception handler.")
error_logger.exception(e)
# ----------------------------------------------

return

# -------------------------------------------- #
Expand Down Expand Up @@ -1559,7 +1534,6 @@ async def _startup(self):
if self.state.primary:
# TODO:
# - Raise warning if secondary apps have error handler config
ErrorHandler.finalize(self.error_handler, config=self.config)
if self.config.TOUCHUP:
TouchUp.run(self)

Expand Down
17 changes: 2 additions & 15 deletions sanic/config.py
Expand Up @@ -36,7 +36,6 @@
"NOISY_EXCEPTIONS": False,
"PROXIES_COUNT": None,
"REAL_IP_HEADER": None,
"REGISTER": True,
"REQUEST_BUFFER_SIZE": 65536, # 64 KiB
"REQUEST_MAX_HEADER_SIZE": 8192, # 8 KiB, but cannot exceed 16384
"REQUEST_ID_HEADER": "X-Request-ID",
Expand Down Expand Up @@ -84,7 +83,6 @@ class Config(dict, metaclass=DescriptorMeta):
NOISY_EXCEPTIONS: bool
PROXIES_COUNT: Optional[int]
REAL_IP_HEADER: Optional[str]
REGISTER: bool
REQUEST_BUFFER_SIZE: int
REQUEST_MAX_HEADER_SIZE: int
REQUEST_ID_HEADER: str
Expand All @@ -111,7 +109,6 @@ def __init__(
super().__init__({**DEFAULT_CONFIG, **defaults})

self._converters = [str, str_to_bool, float, int]
self._LOGO = ""

if converters:
for converter in converters:
Expand Down Expand Up @@ -168,24 +165,14 @@ def _post_set(self, attr, value) -> None:
"REQUEST_MAX_SIZE",
):
self._configure_header_size()
if attr == "LOGO":
self._LOGO = value
deprecation(
"Setting the config.LOGO is deprecated and will no longer "
"be supported starting in v22.6.",
22.6,
)
elif attr == "LOCAL_CERT_CREATOR" and not isinstance(

if attr == "LOCAL_CERT_CREATOR" and not isinstance(
self.LOCAL_CERT_CREATOR, LocalCertCreator
):
self.LOCAL_CERT_CREATOR = LocalCertCreator[
self.LOCAL_CERT_CREATOR.upper()
]

@property
def LOGO(self):
return self._LOGO

@property
def FALLBACK_ERROR_FORMAT(self) -> str:
if self._FALLBACK_ERROR_FORMAT is _default:
Expand Down
95 changes: 9 additions & 86 deletions sanic/handlers.py
@@ -1,21 +1,13 @@
from __future__ import annotations

from typing import Dict, List, Optional, Tuple, Type, Union

from sanic.config import Config
from sanic.errorpages import (
DEFAULT_FORMAT,
BaseRenderer,
TextRenderer,
exception_response,
)
from typing import Dict, List, Optional, Tuple, Type

from sanic.errorpages import BaseRenderer, TextRenderer, exception_response
from sanic.exceptions import (
HeaderNotFound,
InvalidRangeType,
RangeNotSatisfiable,
SanicException,
)
from sanic.helpers import Default, _default
from sanic.log import deprecation, error_logger
from sanic.models.handler_types import RouteHandler
from sanic.response import text
Expand All @@ -36,91 +28,22 @@ class ErrorHandler:

def __init__(
self,
fallback: Union[str, Default] = _default,
base: Type[BaseRenderer] = TextRenderer,
):
self.cached_handlers: Dict[
Tuple[Type[BaseException], Optional[str]], Optional[RouteHandler]
] = {}
self.debug = False
self._fallback = fallback
self.base = base

if fallback is not _default:
self._warn_fallback_deprecation()

@property
def fallback(self): # no cov
# This is for backwards compat and can be removed in v22.6
if self._fallback is _default:
return DEFAULT_FORMAT
return self._fallback

@fallback.setter
def fallback(self, value: str): # no cov
self._warn_fallback_deprecation()
if not isinstance(value, str):
raise SanicException(
f"Cannot set error handler fallback to: value={value}"
)
self._fallback = value

@staticmethod
def _warn_fallback_deprecation():
@classmethod
def finalize(cls, *args, **kwargs):
deprecation(
"Setting the ErrorHandler fallback value directly is "
"deprecated and no longer supported. This feature will "
"be removed in v22.6. Instead, use "
"app.config.FALLBACK_ERROR_FORMAT.",
22.6,
"ErrorHandler.finalize is deprecated and no longer needed. "
"Please remove update your code to remove it. ",
22.12,
)

@classmethod
def _get_fallback_value(cls, error_handler: ErrorHandler, config: Config):
if error_handler._fallback is not _default:
if config._FALLBACK_ERROR_FORMAT == error_handler._fallback:
return error_handler.fallback

error_logger.warning(
"Conflicting error fallback values were found in the "
"error handler and in the app.config while handling an "
"exception. Using the value from app.config."
)
return config.FALLBACK_ERROR_FORMAT

@classmethod
def finalize(
cls,
error_handler: ErrorHandler,
config: Config,
fallback: Optional[str] = None,
):
if fallback:
deprecation(
"Setting the ErrorHandler fallback value via finalize() "
"is deprecated and no longer supported. This feature will "
"be removed in v22.6. Instead, use "
"app.config.FALLBACK_ERROR_FORMAT.",
22.6,
)

if not fallback:
fallback = config.FALLBACK_ERROR_FORMAT

if fallback != DEFAULT_FORMAT:
if error_handler._fallback is not _default:
error_logger.warning(
f"Setting the fallback value to {fallback}. This changes "
"the current non-default value "
f"'{error_handler._fallback}'."
)
error_handler._fallback = fallback

if not isinstance(error_handler, cls):
error_logger.warning(
f"Error handler is non-conforming: {type(error_handler)}"
)

def _full_lookup(self, exception, route_name: Optional[str] = None):
return self.lookup(exception, route_name)

Expand Down Expand Up @@ -237,7 +160,7 @@ def default(self, request, exception):
:return:
"""
self.log(request, exception)
fallback = ErrorHandler._get_fallback_value(self, request.app.config)
fallback = request.app.config.FALLBACK_ERROR_FORMAT
return exception_response(
request,
exception,
Expand Down

0 comments on commit 13d5a44

Please sign in to comment.