Skip to content

Commit

Permalink
Base the App on the Flask Sansio version
Browse files Browse the repository at this point in the history
This removes a lot of code and matches Flask's API exactly, thereby
bringing Quart and Flask closer together
  • Loading branch information
pgjones committed Aug 15, 2023
1 parent 380cb63 commit 0849cde
Show file tree
Hide file tree
Showing 18 changed files with 603 additions and 1,827 deletions.
1,496 changes: 578 additions & 918 deletions src/quart/app.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/quart/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def _convert_version(raw: str) -> List[int]:


async def _handle_exception(app: "Quart", error: Exception) -> Response:
if not app.testing and app.propagate_exceptions:
if not app.testing and app.config["PROPAGATE_EXCEPTIONS"]:
return await traceback_response(error)
else:
raise error
14 changes: 7 additions & 7 deletions src/quart/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from aiofiles import open as async_open
from aiofiles.base import AiofilesContextManager
from aiofiles.threadpool.binary import AsyncBufferedReader
from flask.sansio.app import App
from flask.sansio.blueprints import ( # noqa
Blueprint as SansioBlueprint,
BlueprintSetupState as BlueprintSetupState,
Expand All @@ -30,7 +31,6 @@
)

if t.TYPE_CHECKING:
from .app import Quart
from .wrappers import Response

T_after_serving = t.TypeVar("T_after_serving", bound=AfterServingCallable)
Expand Down Expand Up @@ -208,9 +208,9 @@ def book(page):
return self.add_url_rule(
rule,
endpoint,
view_func, # type: ignore[arg-type]
view_func,
methods={"GET"},
is_websocket=True,
websocket=True,
**options,
)

Expand Down Expand Up @@ -372,7 +372,7 @@ def teardown():
self.record_once(lambda state: state.app.teardown_websocket(func))
return func

def _merge_blueprint_funcs(self, app: Quart, name: str) -> None:
def _merge_blueprint_funcs(self, app: App, name: str) -> None:
super()._merge_blueprint_funcs(app, name)

def extend(bp_dict: dict, parent_dict: dict) -> None:
Expand All @@ -389,7 +389,7 @@ def extend(bp_dict: dict, parent_dict: dict) -> None:
for code, code_values in value.items()
},
)
app.error_handler_spec[key] = value # type: ignore[assignment]
app.error_handler_spec[key] = value

extend(self.before_websocket_funcs, app.before_websocket_funcs)
extend(self.after_websocket_funcs, app.after_websocket_funcs)
extend(self.before_websocket_funcs, app.before_websocket_funcs) # type: ignore
extend(self.after_websocket_funcs, app.after_websocket_funcs) # type: ignore
4 changes: 2 additions & 2 deletions src/quart/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ def get_command(self, ctx: click.Context, name: str) -> click.Command:
click.secho(f"Error: {e.format_message()}\n", err=True, fg="red")
return None

return app.cli.get_command(ctx, name) # type: ignore
return app.cli.get_command(ctx, name)

def list_commands(self, ctx: click.Context) -> List[str]:
self._load_plugin_commands()
Expand All @@ -537,7 +537,7 @@ def list_commands(self, ctx: click.Context) -> List[str]:
# Add commands provided by the app, showing an error and
# continuing if the app couldn't be loaded.
try:
rv.update(info.load_app().cli.list_commands(ctx)) # type: ignore
rv.update(info.load_app().cli.list_commands(ctx))
except NoAppException as e:
# When an app couldn't be loaded, show the error message
# without the traceback.
Expand Down
28 changes: 0 additions & 28 deletions src/quart/config.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,10 @@
from __future__ import annotations

import json
from datetime import timedelta
from typing import Any, Callable

from flask.config import Config as FlaskConfig, ConfigAttribute as ConfigAttribute # noqa: F401

DEFAULT_CONFIG = {
"APPLICATION_ROOT": None,
"BODY_TIMEOUT": 60, # Second
"DEBUG": None,
"ENV": None,
"MAX_CONTENT_LENGTH": 16 * 1024 * 1024, # 16 MB Limit
"MAX_COOKIE_SIZE": 4093,
"PERMANENT_SESSION_LIFETIME": timedelta(days=31),
"PREFER_SECURE_URLS": False, # Replaces PREFERRED_URL_SCHEME to allow for WebSocket scheme
"PRESERVE_CONTEXT_ON_EXCEPTION": None,
"PROPAGATE_EXCEPTIONS": None,
"RESPONSE_TIMEOUT": 60, # Second
"SECRET_KEY": None,
"SEND_FILE_MAX_AGE_DEFAULT": timedelta(hours=12),
"SERVER_NAME": None,
"SESSION_COOKIE_DOMAIN": None,
"SESSION_COOKIE_HTTPONLY": True,
"SESSION_COOKIE_NAME": "session",
"SESSION_COOKIE_PATH": None,
"SESSION_COOKIE_SAMESITE": None,
"SESSION_COOKIE_SECURE": False,
"SESSION_REFRESH_EACH_REQUEST": True,
"TEMPLATES_AUTO_RELOAD": None,
"TESTING": False,
"TRAP_HTTP_EXCEPTIONS": False,
}


class Config(FlaskConfig):
def from_prefixed_env(
Expand Down
2 changes: 1 addition & 1 deletion src/quart/ctx.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async def pop(self, exc: Optional[BaseException]) -> None:

async def auto_pop(self, exc: Optional[BaseException]) -> None:
if self.request_websocket.scope.get("_quart._preserve_context", False) or (
exc is not None and self.app.preserve_context_on_exception
exc is not None and self.app.config["PRESERVE_CONTEXT_ON_EXCEPTION"]
):
self.preserved = True
else:
Expand Down
Loading

0 comments on commit 0849cde

Please sign in to comment.