Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2e18004f7 | ||
|
|
bd18ceb442 | ||
|
|
f38d6d760a | ||
|
|
dee4914bdd |
13
CHANGES.md
13
CHANGES.md
@@ -1,8 +1,19 @@
|
||||
# Microdot change log
|
||||
|
||||
**Release 2.0.1** - 2023-12-23
|
||||
|
||||
- Addressed some inadvertent mistakes in the template extensions ([commit](https://github.com/miguelgrinberg/microdot/commit/bd18ceb4424e9dfb52b1e6d498edd260aa24fc53))
|
||||
|
||||
**Release 2.0.0** - 2023-12-22
|
||||
|
||||
- Major redesign switching to asyncio as the base implementation (See the [Migration Guide](https://microdot.readthedocs.io/en/stable/migrating.html) in the docs for details) [#186](https://github.com/miguelgrinberg/microdot/issues/186) ([commit](https://github.com/miguelgrinberg/microdot/commit/20ea305fe793eb206b52af9eb5c5f3c1e9f57dbb))
|
||||
- Major redesign [#186](https://github.com/miguelgrinberg/microdot/issues/186) ([commit](https://github.com/miguelgrinberg/microdot/commit/20ea305fe793eb206b52af9eb5c5f3c1e9f57dbb))
|
||||
- Code reorganization as a `microdot` package
|
||||
- Asyncio is now the core implementation
|
||||
- New support for Server-Sent Events (SSE)
|
||||
- Several extensions redesigned
|
||||
- Support for "partitioned" cookies
|
||||
- [Cross-compiling and freezing](https://microdot.readthedocs.io/en/stable/freezing.html) guidance
|
||||
- A [Migration Guide](https://microdot.readthedocs.io/en/stable/migrating.html) to help transition to version 2 from older releases
|
||||
|
||||
**Release 1.3.4** - 2023-11-08
|
||||
|
||||
|
||||
@@ -32,5 +32,10 @@ describes the backwards incompatible changes that were made.
|
||||
|
||||
## Resources
|
||||
|
||||
- Documentation: [Latest](https://microdot.readthedocs.io/en/latest/) [Stable](https://microdot.readthedocs.io/en/stable/) [Legacy v1.x](https://microdot.readthedocs.io/en/v1/)
|
||||
- Documentation
|
||||
- [Stable](https://microdot.readthedocs.io/en/stable/)
|
||||
- [Latest](https://microdot.readthedocs.io/en/latest/)
|
||||
- Still using version 1?
|
||||
- [Code](https://github.com/miguelgrinberg/microdot/tree/v1)
|
||||
- [Documentation](https://microdot.readthedocs.io/en/v1/)
|
||||
- [Change Log](https://github.com/miguelgrinberg/microdot/blob/main/CHANGES.md)
|
||||
|
||||
@@ -129,11 +129,10 @@ are the asynchronous versions of these two methods.
|
||||
|
||||
The default location from where templates are loaded is the *templates*
|
||||
subdirectory. This location can be changed with the
|
||||
:func:`init_templates <microdot.utemplate.init_templates>` function::
|
||||
:func:`Template.initialize <microdot.utemplate.Template.initialize>` class
|
||||
method::
|
||||
|
||||
from microdot.utemplate import init_templates
|
||||
|
||||
init_templates('my_templates')
|
||||
Template.initialize('my_templates')
|
||||
|
||||
Using the Jinja Engine
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -174,17 +173,15 @@ method, which returns a generator instead of a string.
|
||||
|
||||
The default location from where templates are loaded is the *templates*
|
||||
subdirectory. This location can be changed with the
|
||||
:func:`init_templates <microdot.utemplate.init_templates>` function::
|
||||
:func:`Template.initialize <microdot.jinja.Template.initialize>` class method::
|
||||
|
||||
from microdot.jinja import init_templates
|
||||
Template.initialize('my_templates')
|
||||
|
||||
init_templates('my_templates')
|
||||
|
||||
The ``init_templates()`` function also accepts ``enable_async`` argument, which
|
||||
The ``initialize()`` method also accepts ``enable_async`` argument, which
|
||||
can be set to ``True`` if asynchronous rendering of templates is desired. If
|
||||
this option is enabled, then the
|
||||
:func:`render_async() <microdot.utemplate.Template.render_async>` and
|
||||
:func:`generate_async() <microdot.utemplate.Template.generate_async>` methods
|
||||
:func:`render_async() <microdot.jinja.Template.render_async>` and
|
||||
:func:`generate_async() <microdot.jinja.Template.generate_async>` methods
|
||||
must be used.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.jinja import template, init_templates
|
||||
from microdot.jinja import Template
|
||||
|
||||
init_templates('templates', enable_async=True)
|
||||
Template.initialize('templates', enable_async=True)
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
|
||||
@@ -11,7 +11,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return await template('index.html').render_async(name=name)
|
||||
return await Template('index.html').render_async(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.jinja import template
|
||||
from microdot.jinja import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -7,12 +7,12 @@ Response.default_content_type = 'text/html'
|
||||
|
||||
@app.route('/')
|
||||
async def index(req):
|
||||
return template('page1.html').render(page='Page 1')
|
||||
return Template('page1.html').render(page='Page 1')
|
||||
|
||||
|
||||
@app.route('/page2')
|
||||
async def page2(req):
|
||||
return template('page2.html').render(page='Page 2')
|
||||
return Template('page2.html').render(page='Page 2')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.jinja import template
|
||||
from microdot.jinja import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').render(name=name)
|
||||
return Template('index.html').render(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot.asgi import Microdot, Response
|
||||
from microdot.jinja import template
|
||||
from microdot.jinja import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').render(name=name)
|
||||
return Template('index.html').render(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot.wsgi import Microdot, Response
|
||||
from microdot.jinja import template
|
||||
from microdot.jinja import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').render(name=name)
|
||||
return Template('index.html').render(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.jinja import template
|
||||
from microdot.jinja import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').generate(name=name)
|
||||
return Template('index.html').generate(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.utemplate import template
|
||||
from microdot.utemplate import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return await template('index.html').render_async(name=name)
|
||||
return await Template('index.html').render_async(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.utemplate import template
|
||||
from microdot.utemplate import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -7,12 +7,12 @@ Response.default_content_type = 'text/html'
|
||||
|
||||
@app.route('/')
|
||||
async def index(req):
|
||||
return template('page1.html').render(page='Page 1')
|
||||
return Template('page1.html').render(page='Page 1')
|
||||
|
||||
|
||||
@app.route('/page2')
|
||||
async def page2(req):
|
||||
return template('page2.html').render(page='Page 2')
|
||||
return Template('page2.html').render(page='Page 2')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.utemplate import template
|
||||
from microdot.utemplate import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').render(name=name)
|
||||
return Template('index.html').render(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot.asgi import Microdot, Response
|
||||
from microdot.utemplate import template
|
||||
from microdot.utemplate import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').render(name=name)
|
||||
return Template('index.html').render(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot.wsgi import Microdot, Response
|
||||
from microdot.utemplate import template
|
||||
from microdot.utemplate import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').render(name=name)
|
||||
return Template('index.html').render(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from microdot import Microdot, Response
|
||||
from microdot.utemplate import template
|
||||
from microdot.utemplate import Template
|
||||
|
||||
app = Microdot()
|
||||
Response.default_content_type = 'text/html'
|
||||
@@ -10,7 +10,7 @@ async def index(req):
|
||||
name = None
|
||||
if req.method == 'POST':
|
||||
name = req.form.get('name')
|
||||
return template('index.html').generate(name=name)
|
||||
return Template('index.html').generate(name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "microdot"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
authors = [
|
||||
{ name = "Miguel Grinberg", email = "miguel.grinberg@gmail.com" },
|
||||
]
|
||||
|
||||
@@ -3,36 +3,37 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
_jinja_env = None
|
||||
|
||||
|
||||
def init_templates(template_dir='templates', enable_async=False, **kwargs):
|
||||
"""Initialize the templating subsystem.
|
||||
|
||||
:param template_dir: the directory where templates are stored. This
|
||||
argument is optional. The default is to load templates
|
||||
from a *templates* subdirectory.
|
||||
:param enable_async: set to ``True`` to enable the async rendering engine
|
||||
in Jinja, and the ``render_async()`` and
|
||||
``generate_async()`` methods.
|
||||
:param kwargs: any additional options to be passed to Jinja's
|
||||
``Environment`` class.
|
||||
"""
|
||||
global _jinja_env
|
||||
_jinja_env = Environment(
|
||||
loader=FileSystemLoader(template_dir),
|
||||
autoescape=select_autoescape(),
|
||||
enable_async=enable_async,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
class Template:
|
||||
"""A template object.
|
||||
|
||||
:param template: The filename of the template to render, relative to the
|
||||
configured template directory.
|
||||
"""
|
||||
@classmethod
|
||||
def initialize(cls, template_dir='templates', enable_async=False,
|
||||
**kwargs):
|
||||
"""Initialize the templating subsystem.
|
||||
|
||||
:param template_dir: the directory where templates are stored. This
|
||||
argument is optional. The default is to load
|
||||
templates from a *templates* subdirectory.
|
||||
:param enable_async: set to ``True`` to enable the async rendering
|
||||
engine in Jinja, and the ``render_async()`` and
|
||||
``generate_async()`` methods.
|
||||
:param kwargs: any additional options to be passed to Jinja's
|
||||
``Environment`` class.
|
||||
"""
|
||||
global _jinja_env
|
||||
_jinja_env = Environment(
|
||||
loader=FileSystemLoader(template_dir),
|
||||
autoescape=select_autoescape(),
|
||||
enable_async=enable_async,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def __init__(self, template):
|
||||
if _jinja_env is None: # pragma: no cover
|
||||
init_templates()
|
||||
self.initialize()
|
||||
#: The name of the template
|
||||
self.name = template
|
||||
self.template = _jinja_env.get_template(template)
|
||||
|
||||
@@ -3,30 +3,32 @@ from utemplate import recompile
|
||||
_loader = None
|
||||
|
||||
|
||||
def init_templates(template_dir='templates', loader_class=recompile.Loader):
|
||||
"""Initialize the templating subsystem.
|
||||
|
||||
:param template_dir: the directory where templates are stored. This
|
||||
argument is optional. The default is to load templates
|
||||
from a *templates* subdirectory.
|
||||
:param loader_class: the ``utemplate.Loader`` class to use when loading
|
||||
templates. This argument is optional. The default is
|
||||
the ``recompile.Loader`` class, which automatically
|
||||
recompiles templates when they change.
|
||||
"""
|
||||
global _loader
|
||||
_loader = loader_class(None, template_dir)
|
||||
|
||||
|
||||
class Template:
|
||||
"""A template object.
|
||||
|
||||
:param template: The filename of the template to render, relative to the
|
||||
configured template directory.
|
||||
"""
|
||||
@classmethod
|
||||
def initialize(cls, template_dir='templates',
|
||||
loader_class=recompile.Loader):
|
||||
"""Initialize the templating subsystem.
|
||||
|
||||
:param template_dir: the directory where templates are stored. This
|
||||
argument is optional. The default is to load
|
||||
templates from a *templates* subdirectory.
|
||||
:param loader_class: the ``utemplate.Loader`` class to use when loading
|
||||
templates. This argument is optional. The default
|
||||
is the ``recompile.Loader`` class, which
|
||||
automatically recompiles templates when they
|
||||
change.
|
||||
"""
|
||||
global _loader
|
||||
_loader = loader_class(None, template_dir)
|
||||
|
||||
def __init__(self, template):
|
||||
if _loader is None: # pragma: no cover
|
||||
init_templates()
|
||||
self.initialize()
|
||||
#: The name of the template
|
||||
self.name = template
|
||||
self.template = _loader.load(template)
|
||||
|
||||
@@ -2,10 +2,10 @@ import asyncio
|
||||
import sys
|
||||
import unittest
|
||||
from microdot import Microdot
|
||||
from microdot.jinja import Template, init_templates
|
||||
from microdot.jinja import Template
|
||||
from microdot.test_client import TestClient
|
||||
|
||||
init_templates('tests/templates')
|
||||
Template.initialize('tests/templates')
|
||||
|
||||
|
||||
@unittest.skipIf(sys.implementation.name == 'micropython',
|
||||
@@ -49,7 +49,7 @@ class TestJinja(unittest.TestCase):
|
||||
self.assertEqual(res.body, b'Hello, foo!')
|
||||
|
||||
def test_render_async_template_in_app(self):
|
||||
init_templates('tests/templates', enable_async=True)
|
||||
Template.initialize('tests/templates', enable_async=True)
|
||||
|
||||
app = Microdot()
|
||||
|
||||
@@ -62,10 +62,10 @@ class TestJinja(unittest.TestCase):
|
||||
self.assertEqual(res.status_code, 200)
|
||||
self.assertEqual(res.body, b'Hello, foo!')
|
||||
|
||||
init_templates('tests/templates')
|
||||
Template.initialize('tests/templates')
|
||||
|
||||
def test_generate_async_template_in_app(self):
|
||||
init_templates('tests/templates', enable_async=True)
|
||||
Template.initialize('tests/templates', enable_async=True)
|
||||
|
||||
app = Microdot()
|
||||
|
||||
@@ -78,4 +78,4 @@ class TestJinja(unittest.TestCase):
|
||||
self.assertEqual(res.status_code, 200)
|
||||
self.assertEqual(res.body, b'Hello, foo!')
|
||||
|
||||
init_templates('tests/templates')
|
||||
Template.initialize('tests/templates')
|
||||
|
||||
@@ -2,9 +2,9 @@ import asyncio
|
||||
import unittest
|
||||
from microdot import Microdot
|
||||
from microdot.test_client import TestClient
|
||||
from microdot.utemplate import Template, init_templates
|
||||
from microdot.utemplate import Template
|
||||
|
||||
init_templates('tests/templates')
|
||||
Template.initialize('tests/templates')
|
||||
|
||||
|
||||
class TestUTemplate(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user