Documentation updates
This commit is contained in:
28
docs/api.rst
28
docs/api.rst
@@ -60,3 +60,31 @@ and coroutines.
|
||||
:inherited-members:
|
||||
:members:
|
||||
|
||||
``microdot_wsgi`` module
|
||||
------------------------
|
||||
|
||||
The ``microdot_wsgi`` module provides an extended ``Microdot`` class that
|
||||
implements the WSGI protocol and can be used with a complaint WSGI web server
|
||||
such as `Gunicorn <https://gunicorn.org/>`_ or
|
||||
`uWSGI <https://uwsgi-docs.readthedocs.io/en/latest/>`_.
|
||||
|
||||
``Microdot`` class
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: microdot_wsgi.Microdot
|
||||
:members:
|
||||
:exclude-members: shutdown, run
|
||||
|
||||
``microdot_asgi`` module
|
||||
------------------------
|
||||
|
||||
The ``microdot_asgi`` module provides an extended ``Microdot`` class that
|
||||
implements the ASGI protocol and can be used with a complaint ASGI server such
|
||||
as `Uvicorn <https://www.uvicorn.org/>`_.
|
||||
|
||||
``Microdot`` class
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: microdot_asgi.Microdot
|
||||
:members:
|
||||
:exclude-members: shutdown, run
|
||||
|
||||
@@ -5,8 +5,12 @@ Microdot can be installed with ``pip``::
|
||||
|
||||
pip install microdot
|
||||
|
||||
For platforms that do not support or cannot run ``pip``, you can also manually
|
||||
copy and install the ``microdot.py`` and ``microdot_asyncio.py`` source files.
|
||||
For MicroPython, you can install with ``upip``.
|
||||
|
||||
On platforms where ``pip`` or ``upip`` are not viable options, you can manually
|
||||
copy and install the ``microdot.py`` and ``microdot_asyncio.py`` source files
|
||||
from the `GitHub reposutory <https://github.com/miguelgrinberg/microdot>`_
|
||||
into your project directory.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
@@ -352,7 +352,10 @@ class Response():
|
||||
"""An HTTP response class.
|
||||
|
||||
:param body: The body of the response. If a dictionary or list is given,
|
||||
a JSON formatter is used to generate the body.
|
||||
a JSON formatter is used to generate the body. If a file-like
|
||||
object or a generator is given, a streaming response is used.
|
||||
If a string is given, it is encoded from UTF-8. Else, the
|
||||
body should be a byte sequence.
|
||||
:param status_code: The numeric HTTP status code of the response. The
|
||||
default is 200.
|
||||
:param headers: A dictionary of headers to include in the response.
|
||||
|
||||
@@ -44,7 +44,12 @@ class _BodyStream: # pragma: no cover
|
||||
|
||||
|
||||
class Microdot(BaseMicrodot):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.embedded_server = False
|
||||
|
||||
async def asgi_app(self, scope, receive, send):
|
||||
"""An ASGI application."""
|
||||
if scope['type'] != 'http': # pragma: no cover
|
||||
return
|
||||
path = scope['path']
|
||||
@@ -120,18 +125,17 @@ class Microdot(BaseMicrodot):
|
||||
return await self.asgi_app(scope, receive, send)
|
||||
|
||||
def shutdown(self):
|
||||
pid = os.getpgrp() if hasattr(os, 'getpgrp') else os.getpid()
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
if self.embedded_server: # pragma: no cover
|
||||
super().shutdown()
|
||||
else:
|
||||
pid = os.getpgrp() if hasattr(os, 'getpgrp') else os.getpid()
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
|
||||
def run(self, host='0.0.0.0', port=5000, debug=False,
|
||||
**options): # pragma: no cover
|
||||
try:
|
||||
import uvicorn
|
||||
except ImportError: # pragma: no cover
|
||||
raise RuntimeError('The run() method requires uvicorn to be '
|
||||
'installed (i.e. run "pip install uvicorn").')
|
||||
|
||||
self.debug = debug
|
||||
if 'log_level' not in options:
|
||||
options['log_level'] = 'info' if debug else 'error'
|
||||
uvicorn.run(self, host=host, port=port, **options)
|
||||
"""Normally you would not start the server by invoking this method.
|
||||
Instead, start your chosen ASGI web server and pass the ``Microdot``
|
||||
instance as the ASGI application.
|
||||
"""
|
||||
self.embedded_server = True
|
||||
super().run(host=host, port=port, debug=debug, **options)
|
||||
|
||||
@@ -107,7 +107,10 @@ class Response(BaseResponse):
|
||||
"""An HTTP response class.
|
||||
|
||||
:param body: The body of the response. If a dictionary or list is given,
|
||||
a JSON formatter is used to generate the body.
|
||||
a JSON formatter is used to generate the body. If a file-like
|
||||
object or an async generator is given, a streaming response is
|
||||
used. If a string is given, it is encoded from UTF-8. Else,
|
||||
the body should be a byte sequence.
|
||||
:param status_code: The numeric HTTP status code of the response. The
|
||||
default is 200.
|
||||
:param headers: A dictionary of headers to include in the response.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
from microdot import * # noqa: F401, F403
|
||||
@@ -7,7 +6,12 @@ from microdot import Request
|
||||
|
||||
|
||||
class Microdot(BaseMicrodot):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.embedded_server = False
|
||||
|
||||
def wsgi_app(self, environ, start_response):
|
||||
"""A WSGI application callable."""
|
||||
path = environ.get('SCRIPT_NAME', '') + environ.get('PATH_INFO', '')
|
||||
if 'QUERY_STRING' in environ and environ['QUERY_STRING']:
|
||||
path += '?' + environ['QUERY_STRING']
|
||||
@@ -39,20 +43,17 @@ class Microdot(BaseMicrodot):
|
||||
return self.wsgi_app(environ, start_response)
|
||||
|
||||
def shutdown(self):
|
||||
pid = os.getpgrp() if hasattr(os, 'getpgrp') else os.getpid()
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
if self.embedded_server: # pragma: no cover
|
||||
super().shutdown()
|
||||
else:
|
||||
pid = os.getpgrp() if hasattr(os, 'getpgrp') else os.getpid()
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
|
||||
def run(self, host='0.0.0.0', port=5000, debug=False,
|
||||
**options): # pragma: no cover
|
||||
try:
|
||||
from waitress import serve
|
||||
except ImportError: # pragma: no cover
|
||||
raise RuntimeError('The run() method requires Waitress to be '
|
||||
'installed (i.e. run "pip install waitress").')
|
||||
|
||||
self.debug = debug
|
||||
if debug:
|
||||
logger = logging.getLogger('waitress')
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
serve(self, host=host, port=port, **options)
|
||||
"""Normally you would not start the server by invoking this method.
|
||||
Instead, start your chosen WSGI web server and pass the ``Microdot``
|
||||
instance as the WSGI callable.
|
||||
"""
|
||||
self.embedded_server = True
|
||||
super().run(host=host, port=port, debug=debug, **options)
|
||||
|
||||
Reference in New Issue
Block a user