Documentation improvements
This commit is contained in:
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -16,6 +16,7 @@ jobs:
|
||||
- run: python -m pip install --upgrade pip wheel
|
||||
- run: pip install tox tox-gh-actions
|
||||
- run: tox -eflake8
|
||||
- run: tox -edocs
|
||||
tests:
|
||||
name: tests
|
||||
strategy:
|
||||
|
||||
42
docs/api.rst
42
docs/api.rst
@@ -1,8 +1,8 @@
|
||||
API Reference
|
||||
=============
|
||||
|
||||
``microdot`` module
|
||||
-------------------
|
||||
Core API
|
||||
--------
|
||||
|
||||
.. autoclass:: microdot.Microdot
|
||||
:members:
|
||||
@@ -14,51 +14,57 @@ API Reference
|
||||
:members:
|
||||
|
||||
|
||||
``websocket`` extension
|
||||
-----------------------
|
||||
WebSocket
|
||||
---------
|
||||
|
||||
.. automodule:: microdot.websocket
|
||||
:members:
|
||||
|
||||
``utemplate`` templating extension
|
||||
----------------------------------
|
||||
Server-Sent Events (SSE)
|
||||
------------------------
|
||||
|
||||
.. automodule:: microdot.sse
|
||||
:members:
|
||||
|
||||
Templates (uTemplate)
|
||||
---------------------
|
||||
|
||||
.. automodule:: microdot.utemplate
|
||||
:members:
|
||||
|
||||
``jinja`` templating extension
|
||||
------------------------------
|
||||
Templates (Jinja)
|
||||
-----------------
|
||||
|
||||
.. automodule:: microdot.jinja
|
||||
:members:
|
||||
|
||||
``session`` extension
|
||||
---------------------
|
||||
User Sessions
|
||||
-------------
|
||||
|
||||
.. automodule:: microdot.session
|
||||
:members:
|
||||
|
||||
``cors`` extension
|
||||
------------------
|
||||
Cross-Origin Resource Sharing (CORS)
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: microdot.cors
|
||||
:members:
|
||||
|
||||
``test_client`` extension
|
||||
-------------------------
|
||||
Test Client
|
||||
-----------
|
||||
|
||||
.. automodule:: microdot.test_client
|
||||
:members:
|
||||
|
||||
``asgi`` extension
|
||||
------------------
|
||||
ASGI
|
||||
----
|
||||
|
||||
.. autoclass:: microdot.asgi.Microdot
|
||||
:members:
|
||||
:exclude-members: shutdown, run
|
||||
|
||||
``wsgi`` extension
|
||||
-------------------
|
||||
WSGI
|
||||
----
|
||||
|
||||
.. autoclass:: microdot.wsgi.Microdot
|
||||
:members:
|
||||
|
||||
@@ -25,14 +25,15 @@ and incorporated into a custom MicroPython firmware.
|
||||
|
||||
Use the following guidelines to know what files to copy:
|
||||
|
||||
- For a minimal setup with only the base web server functionality, copy
|
||||
* For a minimal setup with only the base web server functionality, copy
|
||||
`microdot.py <https://github.com/miguelgrinberg/microdot/blob/main/src/microdot/microdot.py>`_
|
||||
into your project.
|
||||
- For a configuration that includes one or more optional extensions, create a
|
||||
* For a configuration that includes one or more optional extensions, create a
|
||||
*microdot* directory in your device and copy the following files:
|
||||
- `__init__.py <https://github.com/miguelgrinberg/microdot/blob/main/src/microdot/__init__.py>`_
|
||||
- `microdot.py <https://github.com/miguelgrinberg/microdot/blob/main/src/microdot/microdot.py>`_
|
||||
- any needed `extensions <https://github.com/miguelgrinberg/microdot/tree/main/src/microdot>`_.
|
||||
|
||||
* `__init__.py <https://github.com/miguelgrinberg/microdot/blob/main/src/microdot/__init__.py>`_
|
||||
* `microdot.py <https://github.com/miguelgrinberg/microdot/blob/main/src/microdot/microdot.py>`_
|
||||
* any needed `extensions <https://github.com/miguelgrinberg/microdot/tree/main/src/microdot>`_.
|
||||
|
||||
|
||||
Getting Started
|
||||
|
||||
@@ -45,6 +45,12 @@ class _BodyStream: # pragma: no cover
|
||||
|
||||
|
||||
class Microdot(BaseMicrodot):
|
||||
"""A subclass of the core :class:`Microdot <microdot.Microdot>` class that
|
||||
implements the ASGI protocol.
|
||||
|
||||
This class must be used as the application instance when running under an
|
||||
ASGI web server.
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.embedded_server = False
|
||||
|
||||
@@ -134,7 +134,7 @@ def with_session(f):
|
||||
return 'Hello, World!'
|
||||
|
||||
Note that the decorator does not save the session. To update the session,
|
||||
call the :func:`update_session <microdot.session.update_session>` function.
|
||||
call the :func:`session.save() <microdot.session.SessionDict.save>` method.
|
||||
"""
|
||||
async def wrapper(request, *args, **kwargs):
|
||||
return await invoke_handler(
|
||||
|
||||
@@ -3,6 +3,11 @@ import json
|
||||
|
||||
|
||||
class SSE:
|
||||
"""Server-Sent Events object.
|
||||
|
||||
An object of this class is sent to handler functions to manage the SSE
|
||||
connection.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.event = asyncio.Event()
|
||||
self.queue = []
|
||||
@@ -40,19 +45,9 @@ def sse_response(request, event_function, *args, **kwargs):
|
||||
:param args: additional positional arguments to be passed to the response.
|
||||
:param kwargs: additional keyword arguments to be passed to the response.
|
||||
|
||||
Example::
|
||||
|
||||
@app.route('/events')
|
||||
async def events_route(request):
|
||||
async def events(request, sse):
|
||||
# send an unnamed event with string data
|
||||
await sse.send('hello')
|
||||
# send an unnamed event with JSON data
|
||||
await sse.send({'foo': 'bar'})
|
||||
# send a named event
|
||||
await sse.send('hello', event='greeting')
|
||||
|
||||
return sse_response(request, events)
|
||||
This is a low-level function that can be used to implement a custom SSE
|
||||
endpoint. In general the :func:`microdot.sse.with_sse` decorator should be
|
||||
used instead.
|
||||
"""
|
||||
sse = SSE()
|
||||
|
||||
@@ -95,9 +90,14 @@ def with_sse(f):
|
||||
@app.route('/events')
|
||||
@with_sse
|
||||
async def events(request, sse):
|
||||
for i in range(10):
|
||||
await asyncio.sleep(1)
|
||||
await sse.send(f'{i}')
|
||||
# send an unnamed event with string data
|
||||
await sse.send('hello')
|
||||
|
||||
# send an unnamed event with JSON data
|
||||
await sse.send({'foo': 'bar'})
|
||||
|
||||
# send a named event
|
||||
await sse.send('hello', event='greeting')
|
||||
"""
|
||||
async def sse_handler(request, *args, **kwargs):
|
||||
return sse_response(request, f, *args, **kwargs)
|
||||
|
||||
@@ -5,6 +5,11 @@ from microdot.microdot import MUTED_SOCKET_ERRORS
|
||||
|
||||
|
||||
class WebSocket:
|
||||
"""A WebSocket connection object.
|
||||
|
||||
An instance of this class is sent to handler functions to manage the
|
||||
WebSocket connection.
|
||||
"""
|
||||
CONT = 0
|
||||
TEXT = 1
|
||||
BINARY = 2
|
||||
@@ -26,6 +31,7 @@ class WebSocket:
|
||||
b'Sec-WebSocket-Accept: ' + response + b'\r\n\r\n')
|
||||
|
||||
async def receive(self):
|
||||
"""Receive a message from the client."""
|
||||
while True:
|
||||
opcode, payload = await self._read_frame()
|
||||
send_opcode, data = self._process_websocket_frame(opcode, payload)
|
||||
@@ -35,12 +41,20 @@ class WebSocket:
|
||||
return data
|
||||
|
||||
async def send(self, data, opcode=None):
|
||||
"""Send a message to the client.
|
||||
|
||||
:param data: the data to send, given as a string or bytes.
|
||||
:param opcode: a custom frame opcode to use. If not given, the opcode
|
||||
is ``TEXT`` or ``BINARY`` depending on the type of the
|
||||
data.
|
||||
"""
|
||||
frame = self._encode_websocket_frame(
|
||||
opcode or (self.TEXT if isinstance(data, str) else self.BINARY),
|
||||
data)
|
||||
await self.request.sock[1].awrite(frame)
|
||||
|
||||
async def close(self):
|
||||
"""Close the websocket connection."""
|
||||
if not self.closed: # pragma: no cover
|
||||
self.closed = True
|
||||
await self.send(b'', self.CLOSE)
|
||||
|
||||
@@ -9,6 +9,12 @@ from microdot.websocket import WebSocket, websocket_upgrade, \
|
||||
|
||||
|
||||
class Microdot(BaseMicrodot):
|
||||
"""A subclass of the core :class:`Microdot <microdot.Microdot>` class that
|
||||
implements the WSGI protocol.
|
||||
|
||||
This class must be used as the application instance when running under a
|
||||
WSGI web server.
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.loop = asyncio.new_event_loop()
|
||||
|
||||
13
tox.ini
13
tox.ini
@@ -1,5 +1,5 @@
|
||||
[tox]
|
||||
envlist=flake8,py38,py39,py310,py311,py312,upy,cpy,benchmark
|
||||
envlist=flake8,py38,py39,py310,py311,py312,upy,cpy,benchmark,docs
|
||||
skipsdist=True
|
||||
skip_missing_interpreters=True
|
||||
|
||||
@@ -36,7 +36,6 @@ commands=sh -c "bin/circuitpython run_tests.py"
|
||||
[testenv:upy-mac]
|
||||
allowlist_externals=micropython
|
||||
commands=micropython run_tests.py
|
||||
deps=
|
||||
|
||||
[testenv:benchmark]
|
||||
deps=
|
||||
@@ -59,3 +58,13 @@ deps=
|
||||
flake8
|
||||
commands=
|
||||
flake8 --ignore=W503 --exclude examples/templates/utemplate/templates src tests examples
|
||||
|
||||
[testenv:docs]
|
||||
changedir=docs
|
||||
deps=
|
||||
sphinx
|
||||
pyjwt
|
||||
allowlist_externals=
|
||||
make
|
||||
commands=
|
||||
make html
|
||||
|
||||
Reference in New Issue
Block a user