From 5a1dfec25314d1f59fb66e4586e9286bb2357253 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Tue, 18 Jan 2022 19:57:05 +0000 Subject: [PATCH 1/9] Use AppKey. --- aiohttp_jinja2/__init__.py | 31 +++++++++++++++++-------------- tests/test_context_processors.py | 9 +++++---- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index bca973be..930b052e 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -7,6 +7,7 @@ Awaitable, Callable, Dict, + Final, Iterable, Mapping, Optional, @@ -33,15 +34,14 @@ __all__ = ("setup", "get_env", "render_template", "render_string", "template") - -APP_CONTEXT_PROCESSORS_KEY = "aiohttp_jinja2_context_processors" -APP_KEY = "aiohttp_jinja2_environment" -REQUEST_CONTEXT_KEY = "aiohttp_jinja2_context" - _TemplateReturnType = Awaitable[Union[web.StreamResponse, Mapping[str, Any]]] _SimpleTemplateHandler = Callable[[web.Request], _TemplateReturnType] _ContextProcessor = Callable[[web.Request], Awaitable[Dict[str, Any]]] +APP_CONTEXT_PROCESSORS_KEY: Final = web.AppKey[Iterable[_ContextProcessor]]("APP_CONTEXT_PROCESSORS_KEY") +APP_KEY: Final = web.AppKey[jinja2.Environment]("APP_KEY") +REQUEST_CONTEXT_KEY: Final = "aiohttp_jinja2_context" + _T = TypeVar("_T") _AbstractView = TypeVar("_AbstractView", bound=AbstractView) @@ -69,7 +69,7 @@ def __call__( def setup( app: web.Application, *args: Any, - app_key: str = APP_KEY, + app_key: web.AppKey[jinja2.Environment] = APP_KEY, context_processors: Iterable[_ContextProcessor] = (), filters: Optional[Filters] = None, default_helpers: bool = True, @@ -91,15 +91,18 @@ def setup( return env -def get_env(app: web.Application, *, app_key: str = APP_KEY) -> jinja2.Environment: - return cast(jinja2.Environment, app.get(app_key)) +def get_env(app: web.Application, *, app_key: web.AppKey[jinja2.Environment] = APP_KEY) -> jinja2.Environment: + try: + return app[APP_KEY] + except KeyError: + raise RuntimeError("aiohttp_jinja2.setup(...) must be called first.") def _render_string( template_name: str, request: web.Request, context: Mapping[str, Any], - app_key: str, + app_key: web.AppKey[jinja2.Environment], ) -> Tuple[jinja2.Template, Mapping[str, Any]]: env = request.config_dict.get(app_key) if env is None: @@ -131,7 +134,7 @@ def render_string( request: web.Request, context: Mapping[str, Any], *, - app_key: str = APP_KEY, + app_key: web.AppKey[jinja2.Environment] = APP_KEY, ) -> str: template, context = _render_string(template_name, request, context, app_key) return template.render(context) @@ -142,7 +145,7 @@ async def render_string_async( request: web.Request, context: Mapping[str, Any], *, - app_key: str = APP_KEY, + app_key: web.AppKey[jinja2.Environment] = APP_KEY, ) -> str: template, context = _render_string(template_name, request, context, app_key) return await template.render_async(context) @@ -166,7 +169,7 @@ def render_template( request: web.Request, context: Optional[Mapping[str, Any]], *, - app_key: str = APP_KEY, + app_key: web.AppKey[jinja2.Environment] = APP_KEY, encoding: str = "utf-8", status: int = 200, ) -> web.Response: @@ -180,7 +183,7 @@ async def render_template_async( request: web.Request, context: Optional[Mapping[str, Any]], *, - app_key: str = APP_KEY, + app_key: web.AppKey[jinja2.Environment] = APP_KEY, encoding: str = "utf-8", status: int = 200, ) -> web.Response: @@ -194,7 +197,7 @@ async def render_template_async( def template( template_name: str, *, - app_key: str = APP_KEY, + app_key: web.AppKey[jinja2.Environment] = APP_KEY, encoding: str = "utf-8", status: int = 200, ) -> _TemplateWrapper: diff --git a/tests/test_context_processors.py b/tests/test_context_processors.py index 78dcf0bd..f73a5c3e 100644 --- a/tests/test_context_processors.py +++ b/tests/test_context_processors.py @@ -1,4 +1,4 @@ -from typing import Dict, Union +from typing import Dict, Tuple, Union import jinja2 from aiohttp import web @@ -22,10 +22,11 @@ async def func(request): async def processor(request: web.Request) -> Dict[str, Union[str, int]]: return {"foo": 1, "bar": "should be overwriten"} - app["aiohttp_jinja2_context_processors"] = ( + f: Tuple[aiohttp_jinja2._ContextProcessor, ...] = ( aiohttp_jinja2.request_processor, processor, ) + app[aiohttp_jinja2.APP_CONTEXT_PROCESSORS_KEY] = f app.router.add_get("/", func) @@ -56,7 +57,7 @@ async def func(request): async def subprocessor(request): return {"foo": 1, "bar": "should be overwriten"} - subapp["aiohttp_jinja2_context_processors"] = ( + subapp[aiohttp_jinja2.APP_CONTEXT_PROCESSORS_KEY] = ( aiohttp_jinja2.request_processor, subprocessor, ) @@ -69,7 +70,7 @@ async def subprocessor(request): async def processor(request): return {"baz": 5} - app["aiohttp_jinja2_context_processors"] = ( + app[aiohttp_jinja2.APP_CONTEXT_PROCESSORS_KEY] = ( aiohttp_jinja2.request_processor, processor, ) From 49fa53328b15e0bb7d8fd157887b8fe6638a855b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Jan 2022 19:57:47 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- aiohttp_jinja2/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index 930b052e..95879e12 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -38,7 +38,9 @@ _SimpleTemplateHandler = Callable[[web.Request], _TemplateReturnType] _ContextProcessor = Callable[[web.Request], Awaitable[Dict[str, Any]]] -APP_CONTEXT_PROCESSORS_KEY: Final = web.AppKey[Iterable[_ContextProcessor]]("APP_CONTEXT_PROCESSORS_KEY") +APP_CONTEXT_PROCESSORS_KEY: Final = web.AppKey[Iterable[_ContextProcessor]]( + "APP_CONTEXT_PROCESSORS_KEY" +) APP_KEY: Final = web.AppKey[jinja2.Environment]("APP_KEY") REQUEST_CONTEXT_KEY: Final = "aiohttp_jinja2_context" @@ -91,7 +93,9 @@ def setup( return env -def get_env(app: web.Application, *, app_key: web.AppKey[jinja2.Environment] = APP_KEY) -> jinja2.Environment: +def get_env( + app: web.Application, *, app_key: web.AppKey[jinja2.Environment] = APP_KEY +) -> jinja2.Environment: try: return app[APP_KEY] except KeyError: From 9c5ab51e65afdda95b5e01a9e69c8873b40afdde Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Tue, 18 Jan 2022 19:59:57 +0000 Subject: [PATCH 3/9] Update __init__.py --- aiohttp_jinja2/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index 95879e12..19a5a4eb 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -14,7 +14,6 @@ Tuple, TypeVar, Union, - cast, overload, ) From 766d32b33a4d850c16c69756c15f64152643dffe Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 21 Jan 2022 17:22:07 +0000 Subject: [PATCH 4/9] Update help message. --- aiohttp_jinja2/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index 930b052e..ae79f76a 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -108,8 +108,7 @@ def _render_string( if env is None: text = ( "Template engine is not initialized, " - "call aiohttp_jinja2.setup(..., app_key={}) first" - "".format(app_key) + "call aiohttp_jinja2.setup(...) first" ) # in order to see meaningful exception message both: on console # output and rendered page we add same message to *reason* and From 9a794158980ca5206ba9845f24e97eaad0bda9f6 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sat, 11 Nov 2023 17:30:18 +0000 Subject: [PATCH 5/9] Update to aiohttp 3.9 --- aiohttp_jinja2/__init__.py | 10 ++++------ aiohttp_jinja2/helpers.py | 26 ++++++++++++++++++-------- docs/index.rst | 9 ++++----- requirements.txt | 2 +- setup.py | 2 +- tests/test_jinja_globals.py | 6 +++--- tests/test_simple_renderer.py | 6 +----- 7 files changed, 32 insertions(+), 29 deletions(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index ae0dde3b..b15304e4 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -24,12 +24,13 @@ else: from typing_extensions import Protocol -from .helpers import GLOBAL_HELPERS +from .helpers import GLOBAL_HELPERS, static_root_key from .typedefs import Filters __version__ = "1.5.1" -__all__ = ("setup", "get_env", "render_template", "render_string", "template") +__all__ = ("get_env", "render_string", "render_template", + "setup", "static_root_key", "template") _TemplateReturnType = Awaitable[Union[web.StreamResponse, Mapping[str, Any]]] _SimpleTemplateHandler = Callable[[web.Request], _TemplateReturnType] @@ -107,10 +108,7 @@ def _render_string( ) -> Tuple[jinja2.Template, Mapping[str, Any]]: env = request.config_dict.get(app_key) if env is None: - text = ( - "Template engine is not initialized, " - "call aiohttp_jinja2.setup(...) first" - ) + text = "Template engine is not initialized, call aiohttp_jinja2.setup() first" # in order to see meaningful exception message both: on console # output and rendered page we add same message to *reason* and # *text* arguments. diff --git a/aiohttp_jinja2/helpers.py b/aiohttp_jinja2/helpers.py index 80b60f86..7245ae1d 100644 --- a/aiohttp_jinja2/helpers.py +++ b/aiohttp_jinja2/helpers.py @@ -3,6 +3,7 @@ http://jinja.pocoo.org/docs/dev/api/#jinja2.contextfunction """ import sys +import warnings from typing import Any, Dict, Optional, Union import jinja2 @@ -18,6 +19,8 @@ class _Context(TypedDict, total=False): else: _Context = Dict[str, Any] +static_root_key = web.AppKey("static_root_key", str) + @jinja2.pass_context def url_for( @@ -61,21 +64,28 @@ def url_for( def static_url(context: _Context, static_file_path: str) -> str: """Filter for generating urls for static files. - NOTE: you'll need - to set app['static_root_url'] to be used as the root for the urls returned. + NOTE: you'll need to set app[aiohttp_jinja2.static_root_key] to be used as the + root for the urls returned. Usage: {{ static('styles.css') }} might become "/static/styles.css" or "http://mycdn.example.com/styles.css" """ app = context["app"] try: - static_url = app["static_root_url"] + static_url = app[static_root_key] except KeyError: - raise RuntimeError( - "app does not define a static root url " - "'static_root_url', you need to set the url root " - "with app['static_root_url'] = ''." - ) from None + try: + # TODO (aiohttp 3.10+): Remove this fallback + static_url = app["static_root_url"] + except KeyError: + raise RuntimeError( + "app does not define a static root url, you need to set the url root " + "with app[aiohttp_jinja2.static_root_key] = ''." + ) from None + else: + warnings.warn( + "'static_root_url' is deprecated, use aiohttp_jinja2.static_root_key.", + category=DeprecationWarning, stacklevel=2) return "{}/{}".format(static_url.rstrip("/"), static_file_path.lstrip("/")) diff --git a/docs/index.rst b/docs/index.rst index f3faec90..1fec8624 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -201,14 +201,13 @@ This is useful as it would allow your static path to switch in deployment or testing with just one line. The ``static`` function has similar usage, except it requires you to -set ``static_root_url`` on the app +set ``app[aiohttp_jinja2.static_root_key]``. -.. code-block:: ruby +.. code-block:: python app = web.Application() - aiohttp_jinja2.setup(app, - loader=jinja2.FileSystemLoader('/path/to/templates/folder')) - app['static_root_url'] = '/static' + aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader("/path/to/templates/folder")) + app[aiohttp_jinja2.static_root_key] = "/static" Then in the template:: diff --git a/requirements.txt b/requirements.txt index 4217f7ca..0166eec6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -e . -aiohttp==3.8.6 +aiohttp==3.9.0b1 alabaster>=0.6.2 coverage==7.2.7 jinja2==3.1.2 diff --git a/setup.py b/setup.py index 9accb347..354a6eee 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ def read(f): install_requires = [ - "aiohttp>=3.6.3", + "aiohttp>=3.9.0b1", "jinja2>=3.0.0", 'typing_extensions>=3.7.4; python_version<"3.8"', ] diff --git a/tests/test_jinja_globals.py b/tests/test_jinja_globals.py index 355869cf..11547df1 100644 --- a/tests/test_jinja_globals.py +++ b/tests/test_jinja_globals.py @@ -141,7 +141,7 @@ async def index(request): app, loader=jinja2.DictLoader({"tmpl.jinja2": "{{ static('whatever.js') }}"}) ) - app["static_root_url"] = "/static" + app[aiohttp_jinja2.static_root_key] = "/static" app.router.add_route("GET", "/", index) client = await aiohttp_client(app) @@ -153,7 +153,7 @@ async def index(request): async def test_static_var_missing(aiohttp_client, caplog): async def index(request): - with pytest.raises(RuntimeError, match="static_root_url"): + with pytest.raises(RuntimeError, match="static_root_key"): aiohttp_jinja2.render_template("tmpl.jinja2", request, {}) return web.Response() @@ -166,4 +166,4 @@ async def index(request): client = await aiohttp_client(app) resp = await client.get("/") - assert 200 == resp.status # static_root_url is not set + assert 200 == resp.status # static_root_key is not set diff --git a/tests/test_simple_renderer.py b/tests/test_simple_renderer.py index cbda557b..edfe4e69 100644 --- a/tests/test_simple_renderer.py +++ b/tests/test_simple_renderer.py @@ -107,11 +107,7 @@ async def func(request: web.Request) -> web.Response: app.router.add_route("GET", "/", func) req = make_mocked_request("GET", "/", app=app) - msg = ( - "Template engine is not initialized, " - "call aiohttp_jinja2.setup(..., app_key={}" - ") first".format(aiohttp_jinja2.APP_KEY) - ) + msg = "Template engine is not initialized, call aiohttp_jinja2.setup() first" with pytest.raises(web.HTTPInternalServerError) as ctx: await func(req) From 2028f637b81a72a4799602d6f4c19936a3043fb2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 11 Nov 2023 17:30:29 +0000 Subject: [PATCH 6/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- aiohttp_jinja2/__init__.py | 10 ++++++++-- aiohttp_jinja2/helpers.py | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index b15304e4..1e042ba9 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -29,8 +29,14 @@ __version__ = "1.5.1" -__all__ = ("get_env", "render_string", "render_template", - "setup", "static_root_key", "template") +__all__ = ( + "get_env", + "render_string", + "render_template", + "setup", + "static_root_key", + "template", +) _TemplateReturnType = Awaitable[Union[web.StreamResponse, Mapping[str, Any]]] _SimpleTemplateHandler = Callable[[web.Request], _TemplateReturnType] diff --git a/aiohttp_jinja2/helpers.py b/aiohttp_jinja2/helpers.py index 7245ae1d..7c6132a5 100644 --- a/aiohttp_jinja2/helpers.py +++ b/aiohttp_jinja2/helpers.py @@ -85,7 +85,9 @@ def static_url(context: _Context, static_file_path: str) -> str: else: warnings.warn( "'static_root_url' is deprecated, use aiohttp_jinja2.static_root_key.", - category=DeprecationWarning, stacklevel=2) + category=DeprecationWarning, + stacklevel=2, + ) return "{}/{}".format(static_url.rstrip("/"), static_file_path.lstrip("/")) From 7eab4f7c1d7d956535797783ba829992b8ff2154 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 11 Nov 2023 17:47:54 +0000 Subject: [PATCH 7/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- aiohttp_jinja2/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aiohttp_jinja2/helpers.py b/aiohttp_jinja2/helpers.py index 7198f1bb..756079cd 100644 --- a/aiohttp_jinja2/helpers.py +++ b/aiohttp_jinja2/helpers.py @@ -13,6 +13,7 @@ class _Context(TypedDict, total=False): app: web.Application + static_root_key = web.AppKey("static_root_key", str) From 38a70b0c05d68f8031875bbb1f2c77ae47c516bc Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sat, 11 Nov 2023 20:00:45 +0000 Subject: [PATCH 8/9] Update __init__.py --- aiohttp_jinja2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohttp_jinja2/__init__.py b/aiohttp_jinja2/__init__.py index ac19fa50..b744382b 100644 --- a/aiohttp_jinja2/__init__.py +++ b/aiohttp_jinja2/__init__.py @@ -96,7 +96,7 @@ def get_env( app: web.Application, *, app_key: web.AppKey[jinja2.Environment] = APP_KEY ) -> jinja2.Environment: try: - return app[APP_KEY] + return app[app_key] except KeyError: raise RuntimeError("aiohttp_jinja2.setup(...) must be called first.") From c7b5ede38a986157102845a086029cbc5f9c3e1e Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sat, 18 Nov 2023 14:42:42 +0000 Subject: [PATCH 9/9] Bump to 3.9.0 --- requirements.txt | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0166eec6..4ce93989 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -e . -aiohttp==3.9.0b1 +aiohttp==3.9.0 alabaster>=0.6.2 coverage==7.2.7 jinja2==3.1.2 diff --git a/setup.py b/setup.py index 47cd6b9e..5bca97c3 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,6 @@ def read(f): license="Apache 2", packages=["aiohttp_jinja2"], python_requires=">=3.8", - install_requires=("aiohttp>=3.9.0b1", "jinja2>=3.0.0"), + install_requires=("aiohttp>=3.9.0", "jinja2>=3.0.0"), include_package_data=True, )