From 7af2e62ff14ad1af95abe8ce32816b1709239e1a Mon Sep 17 00:00:00 2001 From: Amin Alaee Date: Thu, 16 Dec 2021 10:08:31 +0100 Subject: [PATCH 1/3] change github issues template --- .github/ISSUE_TEMPLATE/2-bug-report.md | 53 --------------- .github/ISSUE_TEMPLATE/3-feature-request.md | 33 ---------- .github/ISSUE_TEMPLATE/bug-report.yml | 73 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature-request.yml | 36 ++++++++++ 4 files changed, 109 insertions(+), 86 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/2-bug-report.md delete mode 100644 .github/ISSUE_TEMPLATE/3-feature-request.md create mode 100644 .github/ISSUE_TEMPLATE/bug-report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature-request.yml diff --git a/.github/ISSUE_TEMPLATE/2-bug-report.md b/.github/ISSUE_TEMPLATE/2-bug-report.md deleted file mode 100644 index 7c11706b7..000000000 --- a/.github/ISSUE_TEMPLATE/2-bug-report.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -name: Bug report -about: Report a bug to help improve this project ---- - -### Checklist - - - -- [ ] The bug is reproducible against the latest release and/or `master`. -- [ ] There are no similar issues or pull requests to fix it yet. - -### Describe the bug - - - -### To reproduce - - - -### Expected behavior - - - -### Actual behavior - - - -### Debugging material - - - -### Environment - -- OS: -- Python version: -- Starlette version: - -### Additional context - - diff --git a/.github/ISSUE_TEMPLATE/3-feature-request.md b/.github/ISSUE_TEMPLATE/3-feature-request.md deleted file mode 100644 index 97336f516..000000000 --- a/.github/ISSUE_TEMPLATE/3-feature-request.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project. ---- - -### Checklist - - - -- [ ] There are no similar issues or pull requests for this yet. -- [ ] I discussed this idea on the [community chat](https://gitter.im/encode/community) and feedback is positive. - -### Is your feature related to a problem? Please describe. - - - -## Describe the solution you would like. - - - -## Describe alternatives you considered - - - -## Additional context - - diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 000000000..966090b2f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,73 @@ +name: Bug report +description: Report a bug to help improve this project +body: + - type: checkboxes + id: checks + attributes: + label: Checklist + description: Please make sure you check all these items before submitting your bug report. + options: + - label: The bug is reproducible against the latest release or `master`. + required: true + - label: There are no similar issues or pull requests to fix it yet. + required: true + - type: textarea + id: describe + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to reproduce the bug + description: | + Provide a *minimal* example with steps to reproduce the bug locally. + NOTE: try to keep any external dependencies *at an absolute minimum*. + In other words, remove anything that doesn't make the bug go away. + validations: + required: false + - type: textarea + id: expected + attributes: + label: Expected behavior + description: A clear and concise description of what you expected to happen. + validations: + required: false + - type: textarea + id: actual + attributes: + label: Actual behavior + description: A clear and concise description of what actually happened. + validations: + required: false + - type: textarea + id: notes + attributes: + label: Debugging material + description: | + Any tracebacks, screenshots, etc. that can help understanding the problem. + NOTE: + - Please list tracebacks in full (don't truncate them). + - Consider using `
` to make tracebacks/logs collapsible if they're very large (see https://gist.github.com/ericclemmons/b146fe5da72ca1f706b2ef72a20ac39d). + validations: + required: false + - type: textarea + id: environment + attributes: + label: Environment + description: Describe your environment. + placeholder: | + - OS / Python / Starlette version. + validations: + required: true + - type: textarea + id: additional + attributes: + label: Additional context + description: | + Any additional information that can help understanding the problem. + Eg. linked issues, or a description of what you were trying to achieve. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 000000000..baf791041 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,36 @@ +name: Feature Request +description: Suggest an idea for a feature that you would like to see in Starlette +body: + - type: checkboxes + id: checks + attributes: + label: Checklist + description: Please make sure you check all these items before submitting your feature request. + options: + - label: There are no similar issues or pull requests for this yet. + required: true + - label: I discussed this idea on the [community chat](https://gitter.im/encode/community) and feedback is positive. + required: true + - type: textarea + id: problem + attributes: + label: Is your feature related to a problem? Please describe. + description: A clear and concise description of what you are trying to achieve. + placeholder: I want to be able to [...] but I can't because [...] + - type: textarea + id: solution + attributes: + label: Describe the solution you would like. + description: | + A clear and concise description of what you would want to happen. + For API changes, try to provide a code snippet of what you would like the API to look like. + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you considered + description: Please describe any alternative solutions or features you've considered to solve your problem and why they wouldn't solve it. + - type: textarea + id: additional + attributes: + label: Additional context + description: Provide any additional context, screenshots, trace backs, etc. about the feature here. From b27f002bfa1fc646b5b4455cae10c6667aa331c8 Mon Sep 17 00:00:00 2001 From: Amin Alaee Date: Thu, 27 Jan 2022 15:39:59 +0100 Subject: [PATCH 2/3] Update exception handler signature for websockets --- docs/exceptions.md | 3 +++ starlette/_compat.py | 1 + starlette/applications.py | 19 ++++++++----------- tests/test_exceptions.py | 11 ++++++----- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/exceptions.md b/docs/exceptions.md index bf460d229..9b3ed87be 100644 --- a/docs/exceptions.md +++ b/docs/exceptions.md @@ -28,6 +28,9 @@ exception_handlers = { app = Starlette(routes=routes, exception_handlers=exception_handlers) ``` +Exception handlers have the callable signature of `handler(conn, exception) -> response` and +the conn is an `HTTPConnection` or it's subclasses either `Request` or `WebSocket` instance. + If `debug` is enabled and an error occurs, then instead of using the installed 500 handler, Starlette will respond with a traceback response. diff --git a/starlette/_compat.py b/starlette/_compat.py index 116561917..d71a12ae2 100644 --- a/starlette/_compat.py +++ b/starlette/_compat.py @@ -23,6 +23,7 @@ def md5_hexdigest( data, usedforsecurity=usedforsecurity ).hexdigest() + except TypeError: # pragma: no cover def md5_hexdigest(data: bytes, *, usedforsecurity: bool = True) -> str: diff --git a/starlette/applications.py b/starlette/applications.py index ab6792527..ab34e0535 100644 --- a/starlette/applications.py +++ b/starlette/applications.py @@ -5,11 +5,15 @@ from starlette.middleware import Middleware from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.errors import ServerErrorMiddleware -from starlette.requests import Request +from starlette.requests import HTTPConnection from starlette.responses import Response from starlette.routing import BaseRoute, Router from starlette.types import ASGIApp, Receive, Scope, Send +_TYPE_EXCEPTION_HANDLER = typing.Callable[ + [HTTPConnection, Exception], typing.Union[Response, typing.Awaitable[Response]] +] + class Starlette: """ @@ -28,7 +32,7 @@ class Starlette: * **exception_handlers** - A mapping of either integer status codes, or exception class types onto callables which handle the exceptions. Exception handler callables should be of the form - `handler(request, exc) -> response` and may be be either standard functions, or + `handler(conn, exc) -> response` and may be be either standard functions, or async functions. * **on_startup** - A list of callables to run on application startup. Startup handler callables do not take any arguments, and may be be either @@ -43,12 +47,7 @@ def __init__( debug: bool = False, routes: typing.Sequence[BaseRoute] = None, middleware: typing.Sequence[Middleware] = None, - exception_handlers: typing.Mapping[ - typing.Any, - typing.Callable[ - [Request, Exception], typing.Union[Response, typing.Awaitable[Response]] - ], - ] = None, + exception_handlers: typing.Mapping[typing.Any, _TYPE_EXCEPTION_HANDLER] = None, on_startup: typing.Sequence[typing.Callable] = None, on_shutdown: typing.Sequence[typing.Callable] = None, lifespan: typing.Callable[["Starlette"], typing.AsyncContextManager] = None, @@ -73,9 +72,7 @@ def __init__( def build_middleware_stack(self) -> ASGIApp: debug = self.debug error_handler = None - exception_handlers: typing.Dict[ - typing.Any, typing.Callable[[Request, Exception], Response] - ] = {} + exception_handlers: typing.Dict[typing.Any, _TYPE_EXCEPTION_HANDLER] = {} for key, value in self.exception_handlers.items(): if key in (500, Exception): diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 80307a521..8ab785111 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -1,27 +1,28 @@ import pytest from starlette.exceptions import ExceptionMiddleware, HTTPException +from starlette.requests import HTTPConnection from starlette.responses import PlainTextResponse from starlette.routing import Route, Router, WebSocketRoute -def raise_runtime_error(request): +def raise_runtime_error(conn: HTTPConnection): raise RuntimeError("Yikes") -def not_acceptable(request): +def not_acceptable(conn: HTTPConnection): raise HTTPException(status_code=406) -def no_content(request): +def no_content(conn: HTTPConnection): raise HTTPException(status_code=204) -def not_modified(request): +def not_modified(conn: HTTPConnection): raise HTTPException(status_code=304) -def with_headers(request): +def with_headers(conn: HTTPConnection): raise HTTPException(status_code=200, headers={"x-potato": "always"}) From 46db045d4e24d06b86c456e29d150fa74a0f3359 Mon Sep 17 00:00:00 2001 From: Amin Alaee Date: Thu, 27 Jan 2022 15:47:17 +0100 Subject: [PATCH 3/3] lint --- starlette/_compat.py | 1 - 1 file changed, 1 deletion(-) diff --git a/starlette/_compat.py b/starlette/_compat.py index d71a12ae2..116561917 100644 --- a/starlette/_compat.py +++ b/starlette/_compat.py @@ -23,7 +23,6 @@ def md5_hexdigest( data, usedforsecurity=usedforsecurity ).hexdigest() - except TypeError: # pragma: no cover def md5_hexdigest(data: bytes, *, usedforsecurity: bool = True) -> str: