diff --git a/docs/user/tutorial-asgi.rst b/docs/user/tutorial-asgi.rst index 65ffa2fa9..dd7c63b20 100644 --- a/docs/user/tutorial-asgi.rst +++ b/docs/user/tutorial-asgi.rst @@ -180,13 +180,12 @@ We can now implement a basic async image store. Save the following code as class Image: - def __init__(self, config, image_id, size): self._config = config self.image_id = image_id self.size = size - self.modified = datetime.datetime.utcnow() + self.modified = datetime.datetime.now(datetime.timezone.utc) @property def path(self): @@ -206,7 +205,6 @@ We can now implement a basic async image store. Save the following code as class Store: - def __init__(self, config): self._config = config self._images = {} @@ -272,7 +270,6 @@ of images. Place the code below in a file named ``images.py``: class Images: - def __init__(self, config, store): self._config = config self._store = store @@ -967,6 +964,54 @@ adding ``--cov-fail-under=100`` (or any other percent threshold) to our tests in multiple environments would most probably involve running ``coverage`` directly, and combining results. +Debugging ASGI Applications +--------------------------- +(This section also applies to WSGI applications) + +While developing and testing ASGI applications, understanding how to configure +and utilize logging can be helpful, especially when you encounter unexpected +issues or behaviors. + +By default, Falcon does not set up logging for you, +but Python's built-in :mod:`logging` module provides a flexible framework for +emitting and capturing log messages. Here's how you can set up basic logging in +your ASGI Falcon application: + +.. code:: python + + import falcon + import logging + + logging.basicConfig(level=logging.INFO) + + class ErrorResource: + def on_get(self, req, resp): + raise Exception('Something went wrong!') + + app = falcon.App() + app.add_route('/error', ErrorResource()) + + +When the above route is accessed, Falcon will catch the unhandled exception and +automatically log an error message. Below is an example of what the log output +might look like: + +.. code-block:: none + + ERROR:falcon.asgi.app:Unhandled exception in ASGI application + Traceback (most recent call last): + File "path/to/falcon/app.py", line 123, in __call__ + resp = resource.on_get(req, resp) + File "/path/to/your/app.py", line 7, in on_get + raise Exception("Something went wrong!") + Exception: Something went wrong! + + +.. note:: + While logging is helpful for development and debugging, be mindful of logging + sensitive information. Ensure that log files are stored securely and are not + accessible to unauthorized users. + What Now? --------- diff --git a/examples/asgilook/asgilook/store.py b/examples/asgilook/asgilook/store.py index 2633f0ac0..faf873c91 100644 --- a/examples/asgilook/asgilook/store.py +++ b/examples/asgilook/asgilook/store.py @@ -13,7 +13,7 @@ def __init__(self, config, image_id, size): self.image_id = image_id self.size = size - self.modified = datetime.datetime.utcnow() + self.modified = datetime.datetime.now(datetime.timezone.utc) @property def path(self): diff --git a/requirements/tests b/requirements/tests index 19b34bcd3..e3623da8d 100644 --- a/requirements/tests +++ b/requirements/tests @@ -1,5 +1,8 @@ coverage >= 4.1 -pytest +# TODO(vytas): Our use of testtools breaks under pytest 8.2 along the lines of +# https://github.com/pytest-dev/pytest/issues/12263, unpin when fixed +# (or drop support for testtools altogether?) +pytest >= 7.0, < 8.2 pyyaml requests # TODO(vytas): Check if testtools still brings anything to the table, and diff --git a/tox.ini b/tox.ini index c453fbf84..b1559ec23 100644 --- a/tox.ini +++ b/tox.ini @@ -441,7 +441,6 @@ commands = # -------------------------------------------------------------------- [testenv:look] -basepython = python3.10 deps = -r{toxinidir}/examples/look/requirements/test commands = @@ -452,7 +451,7 @@ commands = # -------------------------------------------------------------------- [testenv:asgilook] -basepython = python3.10 +basepython = python3.12 deps = -r{toxinidir}/examples/asgilook/requirements/asgilook -r{toxinidir}/examples/asgilook/requirements/test