aio-libs / aiohttp-jinja2 Goto Github PK
View Code? Open in Web Editor NEWjinja2 template renderer for aiohttp.web
Home Page: http://aiohttp-jinja2.readthedocs.org/
License: Apache License 2.0
jinja2 template renderer for aiohttp.web
Home Page: http://aiohttp-jinja2.readthedocs.org/
License: Apache License 2.0
Dependabot couldn't authenticate with https://pypi.python.org/simple/.
You can provide authentication details in your Dependabot dashboard by clicking into the account menu (in the top right) and selecting 'Config variables'.
Right now I'm trying to configure pypugjs (which worked flawlessly with Flask) with this library.
I'm currently using the Jinja2 configuration that can be found on pypugjs repo, it throws no errors but of course it's not set up with the app.
Please keep in mind that I'm not an expert with aiohttp or jinja2.
Given this code, with aiohttp_jinja2 1.2.0:
#!/usr/bin/env python3
import os
from aiohttp import web
import aiohttp_jinja2
import jinja2
@aiohttp_jinja2.template('foo.txt')
def handler(request):
return {}
app = web.Application()
aiohttp_jinja2.setup(
app,
loader=jinja2.FileSystemLoader(os.path.abspath('./templates')),
context_processors=[aiohttp_jinja2.request_processor]
)
app.router.add_get('/foo.txt', handler)
web.run_app(app)
mypy reports this error:
demo.py:17: error: List item 0 has incompatible type "Callable[[Request], Coroutine[Any, Any, Dict[str, Request]]]"; expected "Callable[[Request], Dict[str, Any]]"
Get
TypeError: get() missing 1 required positional argument: 'request'
when class function have next signature
class IndexView(View):
@aiohttp_jinja2.template('index.html')
async def get(self, request):
return {'name': 'Andrew', 'surname': 'Svetlov'}
Dependabot couldn't authenticate with https://pypi.python.org/simple/.
You can provide authentication details in your Dependabot dashboard by clicking into the account menu (in the top right) and selecting 'Config variables'.
The jinja2 engine does not currently enable autoescaping by default. From http://jinja.pocoo.org/docs/2.10/api/
In future versions of Jinja2 we might enable autoescaping by default for security reasons. As such you are encouraged to explicitly configure autoescaping now instead of relying on the default.
Although the option to configure this is exposed via aiohttp_jinja2.setup, it might be nice to include it as a default option or explicitly call out the need to enable it in examples and in the documentation.
XXS demo:
<!-- index.j2 -->
<html>
<p>No autoescape by default?</p>
<p>{{ thing }}</p>
</html>
# main.py
from aiohttp import web
import aiohttp_jinja2
import jinja2
@aiohttp_jinja2.template('index.j2')
async def index(request):
return { 'thing': '<script>alert(1)</script>' }
app = web.Application()
aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader('.'))
app.router.add_get('/', index)
web.run_app(app)
route= '/b/{a}' name='b'
The code in html
<a href='{{url("b",a=3)}}'>GO to b</a>
I want to get the path is /b/3
TypeError: url() got an unexpected keyword argument 'a'
And I want to know if want to get the path like /b?a=3&c=4
how to do this ?
I want to use nested aiohttp applications on one runner/site. Two uses aiohttp_jinja2. How setup few loaders without singleton?
Hi Everybody!
How to switch lang for current request in gettext?
# ACTIVATE
...
setup_middlewares(self.face)
jinja_environment = aiohttp_jinja2.setup(self.face,
loader=jinja2.FileSystemLoader(os.path.join(BASE_PATH, "app", "templates")),
extensions=['jinja2.ext.i18n'])
jinja_environment.install_gettext_translations(i18n)
handler = self.face.make_handler()
...
# i18.py file
def gettext(msg): # This function takes only one arg. But I want to set lang from request.
lang = "ru_RU"
return AllTranslations[lang].gettext(msg)
This is the url:
('*', '/users/password/edit/{token}', a.SetNewPassword, 'set_new_password')
url = self.request.app.router['set_new_password'].url_for(token=token)
it works fine.
{{ url('set_new_password', token=token) }}
TypeError: url() got an unexpected keyword argument 'token'
https://github.com/aio-libs/aiohttp-jinja2/blob/master/aiohttp_jinja2/__init__.py#L30
url should be deprecated for url_for ?
I have a function:
async def x(id):
return (await db.asd.find_one({"id": x})).name
and I want to call it in template.
@routes.get("/tracks")
@aiohttp_jinja2.template("tracks.jinja2")
async def root(request):
return {"x": x}
But when I do {{ await x(1) }}
error occurs.
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got 'x'
Since jinja 2.9 there is async mode: http://jinja.pocoo.org/docs/2.9/api/#async-support
Hi, I've found a small typing issue after updating aiohttp_jinja2
from 1.1.0
to 1.2.0
mypy report:
app.py:125: error: Dict entry 0 has incompatible type "str": "Callable[[Any], str]"; expected "Callable[..., str]": "Callable[[Any], str]"
and the example code is
def statify(state) -> str:
return json.dumps(state, ensure_ascii=False, indent=3)
aiohttp_jinja2.setup(
app,
loader=jinja2.FileSystemLoader('templates'),
filters={'statify': statify},
)
PyCharm type checker also reports about typing issue
Expected type 'Optional[Iterable[(...) -> str]]', got 'Dict[str, (state: Any) -> str]' instead
The thing is, filters must be either mapping or iterable of key/value pairs, as it's passed to dict.update
method, but current type annotation requires it to be a plain iterable of callables
if filters is not None:
env.filters.update(filters)
On my job people don't use the project but executes template rendering in thread pool.
I don't remember performance boost numbers, @hellysmyle could shed a light on it.
This approach is controversial to async jinja2 mode.
I not sure should we support it or not, should we switch the mode globally in setup()
or use a flag in template
decorator and render_template
function, should we accept specific thread pool instance or use default executor, etc.
The issue is the site for discussion.
I tried to find some info about autoescaping and it is not available in both stable and latest docs builds.
(available in sources).
That is why I guess that current docs stable is of 0.13.0 release or earlier
Hello AIO team.
Firstly, thank you for an awesome piece of software. Really amazing work.
I am however having an issue with the live reloading of the jinja2 templates which we are populating dynamically from a DB and via REST calls to other microservices. The templates do not update with the new data even though we have disabled caching on the jinja2 environment as well as enabled auto reloading:
aiohttp_jinja2.setup(
app,
loader=jinja2.FileSystemLoader(str(THIS_DIR / 'templates')),
auto_reload=True,
cache_size=0
)
We have tried lots of combinations of key word arguments but the above should be correct and it does not work. Any help in this regard would be greatly appreciated.
aiohttp (3.0.7)
aiohttp-debugtoolbar (0.5.0)
aiohttp-devtools (0.8)
aiohttp-jinja2 (0.17.0)
async-timeout (2.0.0)
attrs (17.4.0)
chardet (3.0.4)
click (6.7)
idna (2.6)
idna-ssl (1.0.1)
isort (4.3.4)
Jinja2 (2.10)
MarkupSafe (1.0)
multidict (4.1.0)
pip (9.0.1)
PyYAML (3.12)
setuptools (38.5.2)
watchgod (0.0.3)
wheel (0.30.0)
yarl (1.1.1)
The project started as tiny jinja2
wrapper but it grows slowly.
http://aiohttp-jinja2.readthedocs.io/en/stable/ is cool but I feel a need for separate page with comprehensive descriptions for supported API.
http://aiohttp-jinja2.readthedocs.io/en/stable/#reference is too far from the beginning of text, and it is not full, e.g. http://aiohttp-jinja2.readthedocs.io/en/stable/#aiohttp_jinja2.setup doesn't reflect real setup()
signature.
Any volunteer?
@bmwant maybe?
It does not seem possible to render a 404 (or any non-200) response using render_template()
because it does not have a means to pass arguments to the constructor of web.Response
. The status of the response object cannot be changed after it's initialized, so we need to pass in status=404
.
Related issue: not all my templates will be HTML, so content_type
should probably be an optional argument as well.
For best forwards-compatibility, you may want to send all unknown keyword arguments into web.Response
.
@asvetlov I've added the async functions to the docs, but it doesn't appear to be auto-deployed to the website. So, when you've got a moment, that should get deployed.
Hi,
I'm sorry to spam you today, but could you publish aiohttp_jinja2 on PyPI ?
I'm using it, it will simpler to install instead of via Git repository.
BTW, it works like a charm.
Regards.
Do like this:
REPO_NAME={{ YOUR_REPO_NAME }}
travis encrypt -r "aio-libs/${REPO_NAME}" --api-endpoint 'https://api.travis-ci.com/'
Ref: https://github.com/orgs/aio-libs/teams/admins/discussions/9
@samuelcolvin got write access to the repo.
I didn't ask Samuel for this and didn't make vote poll -- just added him.
Samuel is aiohttp member with write access already, I see his activity in aiohttp-jinja2
project.
Pretty sure the project will have benefits from new Samuel position.
Hi,
my understanding is that if I have a sub app I need to register aiohttp-jinja2 for it too in addition to the main app. That is corroborated by the following code:
from aiohttp import web
import jinja2
import aiohttp_jinja2
@aiohttp_jinja2.template( 'index.htm.j2')
async def index( request: web.Request ) -> web.Response:
return web.Response( text = 'Test' )
@aiohttp_jinja2.template( 'test.htm.j2' )
async def blog_index( request: web.Request ) -> web.Response:
return {}
app = web.Application()
aiohttp_jinja2.setup( app, loader = jinja2.PackageLoader( 'catalysis', 'templates' ) )
blog_app = web.Application();
blog_app.router.add_route( 'GET', '/', blog_index )
app.add_subapp( '/blog', blog_app )
app.router.add_route( 'GET', '/', index )
web.run_app( app )
My hunch is that because template() looks for request.app and that is the equal to the nested application it fails to find the jinja2 env object. I thought of setting up aiohttp-jinja2 for each subapp that needs it but what do you think of a function that falls-back to the previous apps in request.match_info.apps? I probably am going for this idea with a custom loader that can also start from the module of the current app and falls-back if the template is not found which gives a nice opportunity for app specific templates that can reference a base template but wanted to check if someone has a better idea.
We need access to RTD or to create a new project, in order to enable the PR status check.
See: #778 (comment)
@template
should be applied to coroutines that are accept only one position argument request.
Processing optional response param makes a mess.
Continuing from here ..
I am trying to use aiohttp-jinja2 with app.add_subapp(). Unfortunately I am not able to figure out how to use {{ url('named_url') }}
in case of subapps.
I followed the docs and now I am using it as following:
main.py
app.router.add_route('GET', '/', Index)
app.add_subapp(r'/api/v1/todo', todos_app)
app['todos_app'] = todos_app
index_handler.py
import aiohttp_jinja2
from aiohttp import web
class Index(web.View):
"""Index page for the server."""
@aiohttp_jinja2.template('index.html')
async def get(self):
"""Return a simple page with urls."""
todos_app = self.request.app['todos_app']
return {
'new_todo_url': todos_app.router['new_todo'].url_for(),
}
And
index.html
<li class="list-group-item"><a href="{{ new_todo_url }}">New Todo</a></li>
I was wondering if there is a more efficient/better way to achieve this, by just using url('subapp_named_resource') ?
Please never use underscores in python-packages names.
Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.
We have a really problem. When our build system convert all dependencies to RPM (using FPM) yum is broken. We are can't use this package in our projects.
I would like to access images, etc from .
or ./static
. See https://github.com/cclauss/where_is_lenna/
Isn't it necessary to add decorator @asyncio.coroutine
right before def middleware(request)
in def context_processors_middleware(app, handler)
?
Allowed types are str and int, everything other like bool or float should be explicitly forbidden
From v1.4.2...v1.5 I can see that the required version of jinja2
that is required has changed from v2 to v3.
However this is a backwards incompatible change in the context of installing the connexion package with aiohttp support.
aaron@eleanor:~$ pip3 install connexion[aiohttp]
...
ERROR: flask 1.1.4 has requirement click<8.0,>=5.1, but you'll have click 8.0.1 which is incompatible.
ERROR: aiohttp-jinja2 1.5 has requirement jinja2>=3.0.0, but you'll have jinja2 2.11.3 which is incompatible.
...
And I would have therefore expected it to require a major version bump (i.e. be part of v2.0.0
).
Please see my issue on the other repo: spec-first/connexion#1416
context_processors_middleware unconditionally sets request[REQUEST_CONTEXT_KEY] to the empty dictionary.
That means that, when nesting applications where both the parent and the child have been set to use jinja2 and context processors, anything added to the request by the parent's processors is cleared whenever a request is routed to the child app.
That prevents from composing context data in the request that comes from both apps.
To see why such composition is desirable, consider plain middlewares adding extra properties to the request, doing request['prop']=value. The handlers for the subapp will see all properties in the request set by the parent app as long as they are not overwritten in the child.
As request[REQUEST_CONTEXT_KEY][whatever] is kind-of an equivalent of request[whatever], but for templates, it makes sense for its value to be merged in the subapp rather than replaced. The code needs to be modified so that request[REQUEST_CONTEXT_KEY] isn't reset if the key is already set.
I've seen this as an issue when sharing the same template loader in both the parent and the child apps. The child app wouldn't see results from the parent context processors if the child also had its own context processors.
jinja2 template wrong dict
but we have { 'parts' : {RIGHT_DICT} } dict in dict
myargs = {'path': {'question_id' : 1 }}
var_err = str('/pool/{question_id}').format_map(myargs)
var_ok = str('/pool/{question_id}').format_map(myargs['path'])
/usr/lib/python3.6/site-packages/aiohttp_jinja2/helpers.py
if 'query_' in parts:
query = parts.pop('query_')
url = app.router[__route_name].url_for(**parts)
Originally posted by ugyballoons July 22, 2022
Hi,
I'm enjoying working with aiohttp and jinja2.
It's not clear to me how to employ cache busting. Please could someone help?
In the setup I have:
sub_app.add_routes(
[
web.static(
"/static",
Path(__file__).parent / "static",
name="static",
append_version=True,
),
]
)
sub_app["static_root_url"] = "/path-to/static"
env = aiohttp_jinja2.get_env(sub_app)
env.globals.update(
zip=zip,
url_for=web.Resource.url_for
)
and in the template I have:
<link rel="stylesheet" href="{{ url_for('static', filename='stylesheets/main.css') }}">
I feel that I shouldn't be passing url_for
in the globals but if I don't, then jinja complains that there's no such function. Where am I going wrong?
template()
and render_template()
should be async functions, or for backwards compatibility new async versions of the functions should be added.
They should call jinja2.Template.render_async()
, which also requires enable_async
in the environment setup.
See:
https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Environment
https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Template.render_async
https://jinja.palletsprojects.com/en/2.11.x/api/#async-support
Hi,
Is it possible to load templates after setup? Once my site is running I'd like to enable a new page/template.
The "About" box here on GitHub links to http://aiohttp_jinja2.readthedocs.org/
but it should link to https://aiohttp-jinja2.readthedocs.io/ (dash instead of underscore)
I think it's good idea always pass request as first argument. Because it's first argument in django views, messages, render e.t.c.
"/usr/local/lib/python3.8/site-packages/connexion/__init__.py", line 40, in <module>
from .apis.aiohttp_api import AioHttpApi
File "/usr/local/lib/python3.8/site-packages/connexion/apis/aiohttp_api.py", line 9, in <module>
import aiohttp_jinja2
File "/usr/local/lib/python3.8/site-packages/aiohttp_jinja2/__init__.py", line 24, in <module>
from .helpers import GLOBAL_HELPERS
File "/usr/local/lib/python3.8/site-packages/aiohttp_jinja2/helpers.py", line 23, in <module>
@jinja2.contextfunction
AttributeError: module 'jinja2' has no attribute 'contextfunction'
Requirements that we are using currently
aiohttp>=3.7.4
aiohttp-swagger>=1.0.5
aiohttp-jinja2==1.4.2
Look like 1.4.2 is the latest as per github releases.
am i missing anything. Kindly help me.
It is a question, not an issue. Is it intentional?
Thanks.
aiohttp_jinja2\helpers.py:24: DeprecationWarning: 'contextfunction' is renamed to 'pass_context', the old name will be removed in Jinja 3.1
aiohttp_jinja2\helpers.py:62: DeprecationWarning: 'contextfunction' is renamed to 'pass_context', the old name will be removed in Jinja 3.1
There appears to be a 1.1.0
release here, but it can't be installed via pip:
Collecting aiohttp-jinja2==1.1.0 (from -r requirements.txt (line 10))
Could not find a version that satisfies the requirement aiohttp-jinja2==1.1.0 (from -r requirements.txt (line 10)) (from versions: 0.0.1, 0.0.2, 0.1.0, 0.2.1, 0.3.0, 0.3.1, 0.4.0, 0.4.1, 0.4.2, 0.4.3, 0.5.0, 0.6.1, 0.6.2, 0.7.0, 0.8.0, 0.12.0, 0.13.0, 0.14.0, 0.15.0, 0.16.0, 0.17.0, 1.0.0)
No matching distribution found for aiohttp-jinja2==1.1.0 (from -r requirements.txt (line 10))
Need the ability to access the request object and router.url method from the template
Hi everyone,
Excellent work on aiohttp altogether. This isn't an issue per-say but wondering if anyone is planning on a chameleon version? I see you have jinja2 and mako.
typing_extensions
package doesn’t have to be dependency for Python 3.8 and newer. This patch makes the dependency just optional.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.