microdot 2.6.0__tar.gz → 2.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {microdot-2.6.0/src/microdot.egg-info → microdot-2.6.1}/PKG-INFO +1 -1
- microdot-2.6.1/docs/implementation/type_hints.rst +16 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/index.rst +2 -2
- {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/concurrency.rst +4 -4
- {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/responses.rst +1 -1
- {microdot-2.6.0 → microdot-2.6.1}/pyproject.toml +1 -1
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/__init__.py +1 -1
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/microdot.py +3 -1
- {microdot-2.6.0 → microdot-2.6.1/src/microdot.egg-info}/PKG-INFO +1 -1
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/SOURCES.txt +1 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_response.py +7 -0
- {microdot-2.6.0 → microdot-2.6.1}/LICENSE +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/MANIFEST.in +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/README.md +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/Makefile +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/_static/css/custom.css +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/asgi.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/auth.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/cors.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/csrf.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/index.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/jinja.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/login.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/microdot.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/multipart.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/sessions.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/sse.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/test_client.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/utemplate.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/websocket.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/api/wsgi.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/conf.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/auth.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/cors.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/csrf.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/index.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/login.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/multipart.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/production.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/sessions.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/sse.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/templates.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/test_client.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/websocket.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/implementation/freezing.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/implementation/index.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/implementation/migrating.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/intro.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/make.bat +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/defining-routes.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/index.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/intro.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/request-object.rst +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/setup.cfg +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/__init__.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/asgi.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/asgi.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/auth.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/auth.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/cors.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/cors.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/csrf.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/csrf.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/helpers.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/helpers.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/jinja.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/jinja.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/login.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/login.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/microdot.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/multipart.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/multipart.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/py.typed +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/session.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/session.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/sse.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/sse.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/test_client.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/test_client.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/utemplate.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/utemplate.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/websocket.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/websocket.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/wsgi.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot/wsgi.pyi +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/dependency_links.txt +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/not-zip-safe +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/requires.txt +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/top_level.txt +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/__init__.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.bin +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.css +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.gif +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.gz +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.html +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.jpg +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.js +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.json +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.png +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.txt +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.txt.gz +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/mock_socket.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/templates/hello.jinja.txt +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/templates/hello.utemplate.txt +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/templates/hello_utemplate_txt.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_asgi.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_auth.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_cors.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_csrf.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_end2end.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_jinja.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_login.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_microdot.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_multidict.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_multipart.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_request.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_session.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_sse.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_url_pattern.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_urlencode.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_utemplate.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_websocket.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tests/test_wsgi.py +0 -0
- {microdot-2.6.0 → microdot-2.6.1}/tox.ini +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Type Hints
|
|
2
|
+
~~~~~~~~~~
|
|
3
|
+
|
|
4
|
+
Since version 2.6.0, Microdot includes standard Python type hints for all
|
|
5
|
+
public classes, methods, attributes and functions. This allows IDEs such as
|
|
6
|
+
Visual Studio Code, PyCharm and Vim/Neovim to provide type information and
|
|
7
|
+
autocompletion functions as you type.
|
|
8
|
+
|
|
9
|
+
Type hints are provided in standard stub files with the *.pyi* extension.
|
|
10
|
+
Install Microdot with ``pip``, ``uv`` or your favorite installer to have these
|
|
11
|
+
added to your virtual environment.
|
|
12
|
+
|
|
13
|
+
.. note::
|
|
14
|
+
The *.pyi* stub files are only meant to be used on your computer, to help
|
|
15
|
+
your IDE provide better coding assistance while you type. It is not
|
|
16
|
+
necessary to copy these files to your MicroPython device.
|
|
@@ -9,8 +9,8 @@ Microdot
|
|
|
9
9
|
*"The impossibly small web framework for Python and MicroPython"*
|
|
10
10
|
|
|
11
11
|
Microdot is a minimalistic Python web framework inspired by
|
|
12
|
-
`Flask <https://flask.palletsprojects.com/>`_. Given its size, it can run
|
|
13
|
-
systems with limited resources such as microcontrollers. Both standard Python
|
|
12
|
+
`Flask <https://flask.palletsprojects.com/>`_. Given its small size, it can run
|
|
13
|
+
on systems with limited resources such as microcontrollers. Both standard Python
|
|
14
14
|
(CPython) and `MicroPython <https://micropython.org>`_ are supported.
|
|
15
15
|
|
|
16
16
|
.. toctree::
|
|
@@ -8,7 +8,7 @@ that applications must be careful to prevent blocking in their handlers.
|
|
|
8
8
|
^^^^^^^^^^^^^^^^^^^^
|
|
9
9
|
|
|
10
10
|
The recommendation for route handlers in Microdot is to use asynchronous
|
|
11
|
-
functions, declared
|
|
11
|
+
functions, declared with ``async def``. Microdot executes these handler
|
|
12
12
|
functions as native asynchronous tasks. The standard considerations for writing
|
|
13
13
|
asynchronous code apply, and in particular blocking calls should be avoided to
|
|
14
14
|
ensure the application runs smoothly and is always responsive.
|
|
@@ -24,9 +24,9 @@ When running on CPython, Microdot executes synchronous handlers in a
|
|
|
24
24
|
`thread executor <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor>`_,
|
|
25
25
|
which uses a thread pool. The use of blocking or CPU intensive code in these
|
|
26
26
|
handlers does not have such a negative effect on the application, because
|
|
27
|
-
handlers
|
|
28
|
-
hand, the application will be affected by threading issues
|
|
29
|
-
by the Global Interpreter Lock.
|
|
27
|
+
the handlers run on a different threads than the one running the asynchronous
|
|
28
|
+
loop. On the other hand, the application will be affected by threading issues
|
|
29
|
+
such as those caused by the Global Interpreter Lock.
|
|
30
30
|
|
|
31
31
|
Under MicroPython the situation is different. Most microcontroller boards
|
|
32
32
|
do not have or have very limited threading support, so Microdot executes
|
|
@@ -196,5 +196,5 @@ Another option is to create a response object directly in the route function::
|
|
|
196
196
|
Standard cookies do not offer sufficient privacy and security controls, so
|
|
197
197
|
never store sensitive information in them unless you are adding additional
|
|
198
198
|
protection mechanisms such as encryption or cryptographic signing. The
|
|
199
|
-
:ref:`session <
|
|
199
|
+
:ref:`session <Secure User Sessions>` extension implements signed
|
|
200
200
|
cookies that prevent tampering by malicious actors.
|
|
@@ -630,6 +630,8 @@ class Response:
|
|
|
630
630
|
http_cookie += '; HttpOnly'
|
|
631
631
|
if partitioned:
|
|
632
632
|
http_cookie += '; Partitioned'
|
|
633
|
+
if '\r' in http_cookie or '\n' in http_cookie:
|
|
634
|
+
raise ValueError('invalid cookie')
|
|
633
635
|
if 'Set-Cookie' in self.headers:
|
|
634
636
|
self.headers['Set-Cookie'].append(http_cookie)
|
|
635
637
|
else:
|
|
@@ -762,7 +764,7 @@ class Response:
|
|
|
762
764
|
:param status_code: The 3xx status code to use for the redirect. The
|
|
763
765
|
default is 302.
|
|
764
766
|
"""
|
|
765
|
-
if '\
|
|
767
|
+
if '\r' in location or '\n' in location:
|
|
766
768
|
raise ValueError('invalid redirect URL')
|
|
767
769
|
return cls(status_code=status_code, headers={'Location': location})
|
|
768
770
|
|
|
@@ -39,6 +39,7 @@ docs/extensions/websocket.rst
|
|
|
39
39
|
docs/implementation/freezing.rst
|
|
40
40
|
docs/implementation/index.rst
|
|
41
41
|
docs/implementation/migrating.rst
|
|
42
|
+
docs/implementation/type_hints.rst
|
|
42
43
|
docs/users-guide/concurrency.rst
|
|
43
44
|
docs/users-guide/defining-routes.rst
|
|
44
45
|
docs/users-guide/index.rst
|
|
@@ -194,6 +194,13 @@ class TestResponse(unittest.TestCase):
|
|
|
194
194
|
secure=True, http_only=True)
|
|
195
195
|
res.delete_cookie('foo8', http_only=True)
|
|
196
196
|
res.delete_cookie('foo9', path='/s')
|
|
197
|
+
with self.assertRaises(ValueError):
|
|
198
|
+
res.set_cookie('foo1', 'bar1\r\nSet-Cookie: foo2=bar2')
|
|
199
|
+
with self.assertRaises(ValueError):
|
|
200
|
+
res.set_cookie('foo1', 'bar1',
|
|
201
|
+
domain='example.com\r\nSet-Cookie: foo2=bar2')
|
|
202
|
+
with self.assertRaises(ValueError):
|
|
203
|
+
res.set_cookie('foo1', 'bar1', path='/\r\nSet-Cookie: foo2=bar2')
|
|
197
204
|
self.assertEqual(res.headers, {'Set-Cookie': [
|
|
198
205
|
'foo1=bar1',
|
|
199
206
|
'foo2=bar2; Path=/; Partitioned',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|