Compare commits

...

73 Commits

Author SHA1 Message Date
Adam Hopkins
d9f7086ee6
Add color changes 2023-02-16 14:59:09 +02:00
SML
26e999dec0 Switch blue to code block orange in sanic docs. Add sanic highlight override. Add darker sanic background (111) as option but in the comments so we can switch back if need be. 2023-02-09 16:49:16 +08:00
SML
8f305047c0 Add header background, change all dark theme grays to neutral grays. 2023-02-09 16:35:20 +08:00
SML
59f9b5cc28 Ensure sanic brand color be the same in dark mode. 2023-02-09 16:23:01 +08:00
SML
94eff28fda Add tab hover shadow definition. Intended to have better hover accents for light theme. 2023-02-09 07:03:09 +08:00
SML
c111d93840 Define highlight and tab colors as variables 2023-02-09 06:46:13 +08:00
SML
3587a4fe15 Define sanic-background, sanic-text as top-level colors. Restructure color schemes to top of definition. 2023-02-09 06:13:00 +08:00
SML
51a9605668 Soften lightmode text color 2023-02-09 06:08:00 +08:00
SML
14f16352fc Add tracerite tab color with new sanic-tab variable. 2023-02-09 06:07:45 +08:00
SML
ecf34896c8 Add margins for h3. Probably should be done in the tracerite package. 2023-02-09 04:56:30 +08:00
SML
e544cd8af6 Tweak color scheme for dark themes 2023-02-09 04:55:57 +08:00
SML
aa8af0dcea invalid text justify css 2023-02-09 03:36:20 +08:00
SML
db0b9046d7 Add padding for main container so text doesn’t touch screen boundary 2023-02-09 00:39:26 +08:00
SML
f798eda446 Remove forced hanging emoji from error header 2023-02-09 00:36:20 +08:00
SML
21ad1ae61b Remove tab styling 2023-02-09 00:14:06 +08:00
SML
d8bf65ad1b Tweak colors for dark mode 2023-02-09 00:13:39 +08:00
SML
844cab2d6b Tweak colors for light mode 2023-02-09 00:07:29 +08:00
SML
b0cb01d1a4 Add color sections for dark mode 2023-02-08 23:59:32 +08:00
L. Karkkainen
4c55051442 Fix scrollbar layout problems. 2023-02-08 01:34:41 +00:00
L. Karkkainen
37f3607ebc Friendlify the error page. 2023-02-08 01:26:30 +00:00
L. Karkkainen
7e617c1769 Misc styling 2023-02-07 22:03:10 +00:00
L. Karkkainen
a5f732cc80 Style and layout changes, fix document title. 2023-02-07 21:25:14 +00:00
L. Karkkainen
ce19908bc0 Implement key-value-table as dl instead of table element. 2023-02-07 20:51:25 +00:00
L. Karkkainen
a6efebda56 Cleanup. 2023-02-07 11:00:05 +00:00
L. Karkkainen
da9ff33fa7 Add traceback suppressions to commonly shown internals. 2023-02-07 10:58:46 +00:00
L. Karkkainen
526115c3c5 Fix SVG: alt to desc, whitespace removed 2023-02-06 16:07:58 +00:00
Adam Hopkins
12ba685bf6
Some Sanic branding to error page (#2673)
* Some Sanic branding to error page

* Simplify logo compat
2023-02-06 15:41:01 +00:00
L. Karkkainen
39b98e6b45 Logo shadow to make it show up on white background. 2023-02-06 13:13:01 +00:00
L. Karkkainen
3ddbda61d9 Merge branch 'html-error-handling-suggestions' into niceback-error-handling 2023-02-06 13:02:31 +00:00
L. Karkkainen
68bf26df17 Merge branch 'main' into niceback-error-handling 2023-02-06 12:57:48 +00:00
Adam Hopkins
a773ad2354
Cleanup styles and add Sanic palette 2023-02-06 14:25:22 +02:00
Adam Hopkins
47b2459811
Suggestions 2023-02-06 10:05:51 +02:00
Adam Hopkins
7491d567a3
Merge branch 'niceback-error-handling' of github.com:sanic-org/sanic into niceback-error-handling 2023-02-05 22:13:03 +02:00
L. Karkkainen
783a29bc0b Require tracerite=>1.0.0 2023-02-05 18:49:27 +00:00
L. Karkkainen
cf76c05d3f CSS loading with STYLE_APPEND 2023-02-05 17:26:58 +00:00
Adam Hopkins
d6f2613623
Merge branch 'main' of github.com:sanic-org/sanic into niceback-error-handling 2023-02-05 18:37:08 +02:00
L. Karkkainen
a6ff13ceed Fallback for route name when no route found. 2023-02-05 16:06:45 +00:00
L. Karkkainen
207f8af11f setup.py 2023-02-05 15:58:25 +00:00
L. Karkkainen
5c65118d12 CSS files now start with comments, none inserted in code. 2023-02-05 15:58:09 +00:00
L. Karkkainen
f4792a2bc6 CSS fixes, incl. scaling layout for small screens. 2023-02-05 15:46:12 +00:00
L. Karkkainen
53b7a5a5a1 Merge branch 'main' into niceback-error-handling 2023-02-05 15:16:05 +00:00
L. Karkkainen
ebc2f46682 Minor style changes, loading TraceRite style and css properly, printing exception extra data. 2023-02-04 00:27:29 +00:00
L. Kärkkäinen
ff47448585
Merge branch 'issue2661' into niceback-error-handling 2023-02-02 14:14:56 +00:00
Adam Hopkins
2df5b19fd4
Sans serif w/ autoindex monospace 2023-01-31 11:09:24 +02:00
Adam Hopkins
5dfd48f855
Merge branch 'main' of github.com:sanic-org/sanic into issue2661 2023-01-31 10:44:49 +02:00
Adam Hopkins
ddf3a49988
Remove accidental file 2023-01-31 10:43:19 +02:00
Adam Hopkins
1b43aa5f2f
No auto registration of fallback error handlers 2023-01-31 10:40:47 +02:00
Adam Hopkins
713abe3cf2
Merge branch 'issue2661' of github.com:sanic-org/sanic into issue2661 2023-01-31 10:04:46 +02:00
Adam Hopkins
b46b81d43a
Set styles 2023-01-31 10:03:39 +02:00
L. Kärkkäinen
4f000ab59c
Define colors for light/default mode as well.
The background is not always white by default (e.g. when in an iframe), so it needs to be defined or text may become invisible (just had this problem today). I've taken the opportunity to make it slightly less bright as well.
2023-01-28 23:36:42 +00:00
L. Kärkkäinen
ae757c8ad6
Merge branch 'issue2661' into niceback-error-handling 2023-01-28 23:29:14 +00:00
Adam Hopkins
f30f53f67d
Move DirectoryHandler to app instance 2023-01-28 23:25:25 +02:00
L. Karkkainen
ea09906e0a Refactored to sanic.pages.error module. Traceback and style tuning. Print also headers, and for other than 500 errors as well. 500 error message text UX workaround. 2023-01-27 18:50:35 +00:00
L. Karkkainen
77bdfa14ed HTML error formatting rebuilt on top of BasePage, and using external module niceback to do the tracebacks. 2023-01-27 06:45:49 +00:00
L. Karkkainen
faf1ff8d4f Fix the document title (needs positional argument). 2023-01-27 05:39:45 +00:00
L. Karkkainen
b5175238fb URL sanitation. 2023-01-27 05:31:52 +00:00
L. Karkkainen
32d62c2db4 Style tweaks 2023-01-27 05:24:02 +00:00
L. Karkkainen
a00ec8ab37 Better UX for empty folders. 2023-01-27 04:38:49 +00:00
L. Karkkainen
859a8130c1 Fix Sanic brand colour in breadcrumbs. 2023-01-27 04:38:21 +00:00
L. Karkkainen
2038799d7a Remove parent directory link from table 2023-01-27 04:30:23 +00:00
L. Karkkainen
41da8bbd61 Improve navigation with breadcrumbs 2023-01-27 04:29:15 +00:00
L. Karkkainen
e328d4406b Timestamps a bit less ugly. 2023-01-27 03:23:12 +00:00
L. Karkkainen
d9c883eb9b Add a header bar with Sanic logo. Remove duplicate title element. Avoid escaping in style element and add new styles. 2023-01-27 03:05:00 +00:00
Adam Hopkins
10d4f2803a
Simple server to include autoindex 2023-01-26 18:06:13 +02:00
Adam Hopkins
fa6dbddf69
Style fixes for file table 2023-01-26 17:26:42 +02:00
Adam Hopkins
2c8f1807d8
squash 2023-01-26 17:22:13 +02:00
Adam Hopkins
ca0e933813
No logging of exception 2023-01-26 17:12:51 +02:00
Adam Hopkins
2e36507a60
Refactor to allow for common pages 2023-01-26 16:50:45 +02:00
Adam Hopkins
39a4a75dcb
Add new pages module 2023-01-26 15:52:26 +02:00
Adam Hopkins
e8bb2834d6
Valid HTML5 2023-01-26 00:45:30 +02:00
Adam Hopkins
36e3cc9df7
Use html5tagger for AutoIndex 2023-01-26 00:36:37 +02:00
Adam Hopkins
fed2ef3527
Remove location information 2023-01-24 10:48:54 +02:00
Adam Hopkins
6673acf544
Establish basic file browser and index fallback 2023-01-24 10:27:55 +02:00
16 changed files with 315 additions and 56 deletions

View File

@ -1 +1 @@
__version__ = "22.12.0" __version__ = "23.3.0"

View File

@ -157,6 +157,7 @@ class Sanic(StaticHandleMixin, BaseSanic, StartupMixin, metaclass=TouchUpMeta):
"strict_slashes", "strict_slashes",
"websocket_enabled", "websocket_enabled",
"websocket_tasks", "websocket_tasks",
"wrappers",
) )
_app_registry: Dict[str, "Sanic"] = {} _app_registry: Dict[str, "Sanic"] = {}
@ -875,6 +876,8 @@ class Sanic(StaticHandleMixin, BaseSanic, StartupMixin, metaclass=TouchUpMeta):
:param request: HTTP Request object :param request: HTTP Request object
:return: Nothing :return: Nothing
""" """
__tracebackhide__ = True
await self.dispatch( await self.dispatch(
"http.lifecycle.handle", "http.lifecycle.handle",
inline=True, inline=True,

View File

@ -40,7 +40,7 @@ FULL_COLOR_LOGO = """
""" # noqa """ # noqa
SVG_LOGO = """<svg id=logo alt=Sanic viewBox="0 0 964 279"><path d="M107 222c9-2 10-20 1-22s-20-2-30-2-17 7-16 14 6 10 15 10h30zm115-1c16-2 30-11 35-23s6-24 2-33-6-14-15-20-24-11-38-10c-7 3-10 13-5 19s17-1 24 4 15 14 13 24-5 15-14 18-50 0-74 0h-17c-6 4-10 15-4 20s16 2 23 3zM251 83q9-1 9-7 0-15-10-16h-13c-10 6-10 20 0 22zM147 60c-4 0-10 3-11 11s5 13 10 12 42 0 67 0c5-3 7-10 6-15s-4-8-9-8zm-33 1c-8 0-16 0-24 3s-20 10-25 20-6 24-4 36 15 22 26 27 78 8 94 3c4-4 4-12 0-18s-69 8-93-10c-8-7-9-23 0-30s12-10 20-10 12 2 16-3 1-15-5-18z" fill="#ff0d68"/><path d="M676 74c0-14-18-9-20 0s0 30 0 39 20 9 20 2zm-297-10c-12 2-15 12-23 23l-41 58H340l22-30c8-12 23-13 30-4s20 24 24 38-10 10-17 10l-68 2q-17 1-48 30c-7 6-10 20 0 24s15-8 20-13 20 -20 58-21h50 c20 2 33 9 52 30 8 10 24-4 16-13L384 65q-3-2-5-1zm131 0c-10 1-12 12-11 20v96c1 10-3 23 5 32s20-5 17-15c0-23-3-46 2-67 5-12 22-14 32-5l103 87c7 5 19 1 18-9v-64c-3-10-20-9-21 2s-20 22-30 13l-97-80c-5-4-10-10-18-10zM701 76v128c2 10 15 12 20 4s0-102 0-124s-20-18-20-7z M850 63c-35 0-69-2-86 15s-20 60-13 66 13 8 16 0 1-10 1-27 12-26 20-32 66-5 85-5 31 4 31-10-18-7-54-7M764 159c-6-2-15-2-16 12s19 37 33 43 23 8 25-4-4-11-11-14q-9-3-22-18c-4-7-3-16-10-19zM828 196c-4 0-8 1-10 5s-4 12 0 15 8 2 12 2h60c5 0 10-2 12-6 3-7-1-16-8-16z" fill="#e1e1e1"/></svg>""" # noqa SVG_LOGO_SIMPLE = """<svg id=logo-simple viewBox="0 0 964 279"><desc>Sanic</desc><path d="M107 222c9-2 10-20 1-22s-20-2-30-2-17 7-16 14 6 10 15 10h30zm115-1c16-2 30-11 35-23s6-24 2-33-6-14-15-20-24-11-38-10c-7 3-10 13-5 19s17-1 24 4 15 14 13 24-5 15-14 18-50 0-74 0h-17c-6 4-10 15-4 20s16 2 23 3zM251 83q9-1 9-7 0-15-10-16h-13c-10 6-10 20 0 22zM147 60c-4 0-10 3-11 11s5 13 10 12 42 0 67 0c5-3 7-10 6-15s-4-8-9-8zm-33 1c-8 0-16 0-24 3s-20 10-25 20-6 24-4 36 15 22 26 27 78 8 94 3c4-4 4-12 0-18s-69 8-93-10c-8-7-9-23 0-30s12-10 20-10 12 2 16-3 1-15-5-18z" fill="#ff0d68"/><path d="M676 74c0-14-18-9-20 0s0 30 0 39 20 9 20 2zm-297-10c-12 2-15 12-23 23l-41 58H340l22-30c8-12 23-13 30-4s20 24 24 38-10 10-17 10l-68 2q-17 1-48 30c-7 6-10 20 0 24s15-8 20-13 20 -20 58-21h50 c20 2 33 9 52 30 8 10 24-4 16-13L384 65q-3-2-5-1zm131 0c-10 1-12 12-11 20v96c1 10-3 23 5 32s20-5 17-15c0-23-3-46 2-67 5-12 22-14 32-5l103 87c7 5 19 1 18-9v-64c-3-10-20-9-21 2s-20 22-30 13l-97-80c-5-4-10-10-18-10zM701 76v128c2 10 15 12 20 4s0-102 0-124s-20-18-20-7z M850 63c-35 0-69-2-86 15s-20 60-13 66 13 8 16 0 1-10 1-27 12-26 20-32 66-5 85-5 31 4 31-10-18-7-54-7M764 159c-6-2-15-2-16 12s19 37 33 43 23 8 25-4-4-11-11-14q-9-3-22-18c-4-7-3-16-10-19zM828 196c-4 0-8 1-10 5s-4 12 0 15 8 2 12 2h60c5 0 10-2 12-6 3-7-1-16-8-16z" fill="#1f1f1f"/></svg>""" # noqa
ansi_pattern = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") ansi_pattern = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")

View File

@ -105,6 +105,7 @@ class Blueprint(BaseSanic):
"version", "version",
"version_prefix", "version_prefix",
"websocket_routes", "websocket_routes",
"wrappers",
) )
def __init__( def __init__(

View File

@ -22,6 +22,7 @@ from traceback import extract_tb
from sanic.exceptions import BadRequest, SanicException from sanic.exceptions import BadRequest, SanicException
from sanic.helpers import STATUS_CODES from sanic.helpers import STATUS_CODES
from sanic.pages.error import ErrorPage
from sanic.response import html, json, text from sanic.response import html, json, text
@ -159,36 +160,21 @@ class HTMLRenderer(BaseRenderer):
"{body}" "{body}"
) )
def full(self) -> HTTPResponse: def _page(self, full: bool) -> HTTPResponse:
return html( page = ErrorPage(
self.OUTPUT_HTML.format( title=super().title,
title=self.title, text=super().text,
text=self.text, request=self.request,
style=self.TRACEBACK_STYLE, exc=self.exception,
body=self._generate_body(full=True), full=full,
),
status=self.status,
) )
return html(page.render(), status=self.status, headers=self.headers)
def full(self) -> HTTPResponse:
return self._page(full=True)
def minimal(self) -> HTTPResponse: def minimal(self) -> HTTPResponse:
return html( return self._page(full=False)
self.OUTPUT_HTML.format(
title=self.title,
text=self.text,
style=self.TRACEBACK_STYLE,
body=self._generate_body(full=False),
),
status=self.status,
headers=self.headers,
)
@property
def text(self):
return escape(super().text)
@property
def title(self):
return escape(f"⚠️ {super().title}")
def _generate_body(self, *, full): def _generate_body(self, *, full):
lines = [] lines = []

View File

@ -14,6 +14,7 @@ class MiddlewareMixin(metaclass=SanicMeta):
def __init__(self, *args, **kwargs) -> None: def __init__(self, *args, **kwargs) -> None:
self._future_middleware: List[FutureMiddleware] = [] self._future_middleware: List[FutureMiddleware] = []
self.wrappers = []
def _apply_middleware(self, middleware: FutureMiddleware): def _apply_middleware(self, middleware: FutureMiddleware):
raise NotImplementedError # noqa raise NotImplementedError # noqa
@ -140,3 +141,7 @@ class MiddlewareMixin(metaclass=SanicMeta):
reverse=True, reverse=True,
)[::-1] )[::-1]
) )
def wrap(self, handler):
self.wrappers.append(handler)
return handler

View File

@ -267,11 +267,11 @@ class StartupMixin(metaclass=SanicMeta):
if single_process and legacy: if single_process and legacy:
raise RuntimeError("Cannot run single process and legacy mode") raise RuntimeError("Cannot run single process and legacy mode")
if register_sys_signals is False and not (single_process or legacy): # if register_sys_signals is False and not (single_process or legacy):
raise RuntimeError( # raise RuntimeError(
"Cannot run Sanic.serve with register_sys_signals=False. " # "Cannot run Sanic.serve with register_sys_signals=False. "
"Use either Sanic.serve_single or Sanic.serve_legacy." # "Use either Sanic.serve_single or Sanic.serve_legacy."
) # )
if motd_display: if motd_display:
self.config.MOTD_DISPLAY.update(motd_display) self.config.MOTD_DISPLAY.update(motd_display)

View File

@ -3,16 +3,16 @@ from abc import ABC, abstractmethod
from html5tagger import HTML, Document from html5tagger import HTML, Document
from sanic import __version__ as VERSION from sanic import __version__ as VERSION
from sanic.application.logo import SVG_LOGO from sanic.application.logo import SVG_LOGO_SIMPLE
from sanic.pages.css import CSS from sanic.pages.css import CSS
class BasePage(ABC, metaclass=CSS): # no cov class BasePage(ABC, metaclass=CSS): # no cov
TITLE = "Unknown" TITLE = "Sanic"
CSS: str CSS: str
def __init__(self, debug: bool = True) -> None: def __init__(self, debug: bool = True) -> None:
self.doc = Document(self.TITLE, lang="en") self.doc = None
self.debug = debug self.debug = debug
@property @property
@ -20,6 +20,7 @@ class BasePage(ABC, metaclass=CSS): # no cov
return self.CSS return self.CSS
def render(self) -> str: def render(self) -> str:
self.doc = Document(self.TITLE, lang="en")
self._head() self._head()
self._body() self._body()
self._foot() self._foot()
@ -44,7 +45,7 @@ class BasePage(ABC, metaclass=CSS): # no cov
def _sanic_logo(self) -> None: def _sanic_logo(self) -> None:
self.doc.a( self.doc.a(
HTML(SVG_LOGO), HTML(SVG_LOGO_SIMPLE),
href="https://sanic.dev", href="https://sanic.dev",
target="_blank", target="_blank",
referrerpolicy="no-referrer", referrerpolicy="no-referrer",

View File

@ -24,8 +24,8 @@ class CSS(ABCMeta):
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
Page = super().__new__(cls, name, bases, attrs) Page = super().__new__(cls, name, bases, attrs)
# Use a locally defined STYLE or the one from styles directory # Use a locally defined STYLE or the one from styles directory
s = _extract_style(attrs.get("STYLE"), name) Page.STYLE = _extract_style(attrs.get("STYLE_FILE"), name)
Page.STYLE = f"\n/* {name} */\n{s.strip()}\n" if s else "" Page.STYLE += attrs.get("STYLE_APPEND", "")
# Combine with all ancestor styles # Combine with all ancestor styles
Page.CSS = "".join( Page.CSS = "".join(
Class.STYLE Class.STYLE

105
sanic/pages/error.py Normal file
View File

@ -0,0 +1,105 @@
from typing import Any, Mapping
import tracerite.html
from html5tagger import E
from tracerite import html_traceback, inspector
from sanic.request import Request
from .base import BasePage
# Avoid showing the request in the traceback variable inspectors
inspector.blacklist_types += (Request,)
ENDUSER_TEXT = """We're sorry, but it looks like something went wrong. Please try refreshing the page or navigating back to the homepage. If the issue persists, our technical team is working to resolve it as soon as possible. We apologize for the inconvenience and appreciate your patience.""" # noqa: E501
class ErrorPage(BasePage):
STYLE_APPEND = tracerite.html.style
def __init__(
self,
title: str,
text: str,
request: Request,
exc: Exception,
full: bool,
) -> None:
super().__init__()
# Internal server errors come with the text of the exception,
# which we don't want to show to the user.
# FIXME: Needs to be done in a better way, elsewhere
if "Internal Server Error" in title:
text = "The application encountered an unexpected error and could not continue." # noqa: E501
name = request.app.name.replace("_", " ").strip()
if name.islower():
name = name.title()
self.TITLE = E("Application ").strong(name)(
" cannot handle your request"
)
self.title = title
self.text = text
self.request = request
self.exc = exc
self.full = full
def _head(self) -> None:
self.doc._script(tracerite.html.javascript)
super()._head()
def _body(self) -> None:
debug = self.request.app.debug
try:
route_name = self.request.route.name
except AttributeError:
route_name = "[route not found]"
with self.doc.main:
self.doc.h1(f"⚠️ {self.title}").p(self.text)
# Show context details if available on the exception
context = getattr(self.exc, "context", None)
if context:
self._key_value_table(
"Issue context", "exception-context", context
)
if not debug:
with self.doc.div(id="enduser"):
self.doc.p(ENDUSER_TEXT).p.a("Front Page", href="/")
return
# Show additional details in debug mode,
# open by default for 500 errors
with self.doc.details(open=self.full, class_="smalltext"):
# Show extra details if available on the exception
extra = getattr(self.exc, "extra", None)
if extra:
self._key_value_table(
"Issue extra data", "exception-extra", extra
)
self.doc.summary(
"Details for developers (Sanic debug mode only)"
)
if self.exc:
self.doc.h2(f"Exception in {route_name}:")
self.doc(html_traceback(self.exc, include_js_css=False))
self._key_value_table(
f"{self.request.method} {self.request.path}",
"request-headers",
self.request.headers,
)
def _key_value_table(
self, title: str, table_id: str, data: Mapping[str, Any]
) -> None:
self.doc.h2(title)
with self.doc.dl(id=table_id, class_="key-value-table smalltext"):
for key, value in data.items():
# Reading values may cause a new exception, so suppress it
try:
value = str(value)
except Exception:
value = E.em("Unable to display value")
self.doc.dt.span(key, class_="nobr key").span(": ").dd(value)

View File

@ -1,28 +1,76 @@
/** BasePage **/
:root {
--sanic: #ff0d68;
--sanic-blue: #0092FF;
--sanic-yellow: #FFE900;
--sanic-purple: #833FE3;
--sanic-green: #37ae6f;
--sanic-background: #f1f5f9;
--sanic-text: #1f2937;
--sanic-tab-background: #fff;
--sanic-tab-text: #0f172a;
--sanic-tab-shadow: #adadad;
--sanic-highlight-background: var(--sanic-yellow);
--sanic-highlight-text: var(--sanic-text);
--sanic-header-background: #000;
}
@media (prefers-color-scheme: dark) {
:root {
--sanic-purple: #D246DE;
--sanic-green: #16DB93;
--sanic-background: #111;
--sanic-text: #e7e7e7;
--sanic-tab-background: #484848;
--sanic-tab-text: #e1e1e1;
--sanic-tab-shadow: #000;
--sanic-highlight-background: var(--sanic-yellow);
--sanic-highlight-text: #000;
--sanic-header-background: #000;
}
}
html { html {
font: 16px sans-serif; font: 16px sans-serif;
background: #eee; background: var(--sanic-background);
color: #111; color: var(--sanic-text);
scrollbar-gutter: stable;
overflow: hidden auto;
} }
body { body {
margin: 0; margin: 0;
font-size: 1.25rem; font-size: 1.25rem;
line-height: 125%;
} }
body>* { body>* {
padding: 1rem 2vw; padding: 1rem 2vw;
} }
@media (max-width: 1200px) { @media (max-width: 1000px) {
body>* { body>* {
padding: 0.5rem 1.5vw; padding: 0.5rem 1.5vw;
} }
body { html {
font-size: 1rem; /* Scale everything by rem of 6px-16px by viewport width */
font-size: calc(6px + 10 * 100vw / 1000);
} }
} }
main {
min-height: 70vh;
/* Make sure the footer is closer to bottom */
padding: 1rem 2.5rem;
/* Generous padding for readability */
}
.smalltext {
font-size: 1.0rem;
}
.container { .container {
min-width: 600px; min-width: 600px;
max-width: 1600px; max-width: 1600px;
@ -62,18 +110,19 @@ a:focus {
outline: none; outline: none;
} }
#logo {
height: 1.75rem;
padding: 0 0.25rem;
}
span.icon { span.icon {
margin-right: 1rem; margin-right: 1rem;
} }
#logo-simple {
height: 1.75rem;
padding: 0 0.25rem;
}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
html { #logo-simple path:last-child {
background: #111; fill: #e1e1e1;
color: #ccc;
} }
} }

View File

@ -1,3 +1,4 @@
/** DirectoryPage **/
#breadcrumbs>a:hover { #breadcrumbs>a:hover {
text-decoration: none; text-decoration: none;
} }

View File

@ -0,0 +1,105 @@
/** ErrorPage **/
#enduser {
max-width: 30em;
margin: 5em auto 5em auto;
text-align: justify;
/*text-justify: both;*/
}
#enduser a {
color: var(--sanic-blue);
}
#enduser p:last-child {
text-align: right;
}
summary {
margin-top: 3em;
color: var(--sanic-blue);
cursor: pointer;
}
.tracerite {
--tracerite-var: var(--sanic-blue);
--tracerite-val: var(--sanic-text);
--tracerite-type: var(--sanic-green);
--tracerite-exception: var(--sanic);
--tracerite-highlight: var(--sanic-yellow);
--tracerite-tab: var(--sanic-tab-background);
--tracerite-tab-text: var(--sanic-tab-text);
}
.tracerite>h3 {
margin: 0.5rem 0 !important;
}
.tracerite .traceback-labels button {
font-size: 0.8rem !important;
line-height: 120% !important;
background: var(--tracerite-tab) !important;
color: var(--tracerite-tab-text) !important;
transition: 0.3s;
cursor: pointer;
}
.tracerite .traceback-labels {
padding-top: 5px;
}
.tracerite .traceback-labels button:hover {
filter: contrast(150%) brightness(120%) drop-shadow(0 -0 2px var(--sanic-tab-shadow));
}
.tracerite .traceback-details mark span {
background: var(--sanic-highlight-background) !important;
color: var(--sanic-highlight-text) !important;
}
header {
background: var(--sanic-header-background);
}
h1 {
/*margin-left: -1.5rem; !* Emoji partially in the left margin *!*/
}
h2 {
margin: 1em 0 0.2em 0;
font-size: 1.25rem;
color: var(--sanic-text);
}
dl.key-value-table {
width: 100%;
margin: 0;
display: grid;
grid-template-columns: 1fr 5fr;
grid-gap: .3em;
white-space: pre-wrap;
}
dl.key-value-table * {
margin: 0;
}
dl.key-value-table dt {
color: #888;
word-break: break-word;
}
dl.key-value-table dd {
word-break: break-all;
/* Better breaking for cookies header and such */
}
.tracerite .codeline {
font-family:
"Fira Code",
"Source Code Pro",
Menlo,
Monaco,
Consolas,
Lucida Console,
monospace;
}

View File

@ -39,13 +39,13 @@ class Router(BaseRouter):
extra={"host": host} if host else None, extra={"host": host} if host else None,
) )
except RoutingNotFound as e: except RoutingNotFound as e:
raise NotFound("Requested URL {} not found".format(e.path)) raise NotFound(f"Requested URL {e.path} not found") from None
except NoMethod as e: except NoMethod as e:
raise MethodNotAllowed( raise MethodNotAllowed(
"Method {} not allowed for URL {}".format(method, path), f"Method {method} not allowed for URL {path}",
method=method, method=method,
allowed_methods=e.allowed_methods, allowed_methods=e.allowed_methods,
) ) from None
@lru_cache(maxsize=ROUTER_CACHE_SIZE) @lru_cache(maxsize=ROUTER_CACHE_SIZE)
def get( # type: ignore def get( # type: ignore
@ -61,6 +61,7 @@ class Router(BaseRouter):
correct response correct response
:rtype: Tuple[ Route, RouteHandler, Dict[str, Any]] :rtype: Tuple[ Route, RouteHandler, Dict[str, Any]]
""" """
__tracebackhide__ = True
return self._get(path, method, host) return self._get(path, method, host)
def add( # type: ignore def add( # type: ignore

View File

@ -130,13 +130,14 @@ def _setup_system_signals(
register_sys_signals: bool, register_sys_signals: bool,
loop: asyncio.AbstractEventLoop, loop: asyncio.AbstractEventLoop,
) -> None: # no cov ) -> None: # no cov
print(">>>>>>>>>>>>>>>>>.", run_multiple)
# Ignore SIGINT when run_multiple # Ignore SIGINT when run_multiple
if run_multiple: if run_multiple:
signal_func(SIGINT, SIG_IGN) signal_func(SIGINT, SIG_IGN)
os.environ["SANIC_WORKER_PROCESS"] = "true" os.environ["SANIC_WORKER_PROCESS"] = "true"
# Register signals for graceful termination # Register signals for graceful termination
if register_sys_signals: if register_sys_signals and False:
if OS_IS_WINDOWS: if OS_IS_WINDOWS:
ctrlc_workaround_for_windows(app) ctrlc_workaround_for_windows(app)
else: else:

View File

@ -112,6 +112,7 @@ requirements = [
"websockets>=10.0", "websockets>=10.0",
"multidict>=5.0,<7.0", "multidict>=5.0,<7.0",
"html5tagger>=1.2.1", "html5tagger>=1.2.1",
"tracerite>=1.0.0",
] ]
tests_require = [ tests_require = [