From c4a5f32e19297c498b09b35923a5339dedecb530 Mon Sep 17 00:00:00 2001 From: Vytautas Liuolia Date: Tue, 7 May 2024 20:26:49 +0200 Subject: [PATCH 1/2] chore(CI): pin `pytest` + ASGI tutorial fixes (#2233) --- docs/user/tutorial-asgi.rst | 5 +---- examples/asgilook/asgilook/store.py | 2 +- requirements/tests | 5 ++++- tox.ini | 3 +-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/user/tutorial-asgi.rst b/docs/user/tutorial-asgi.rst index 65ffa2fa9..dff2206b2 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 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 0e6dcd477..e6ca31342 100644 --- a/tox.ini +++ b/tox.ini @@ -435,7 +435,6 @@ commands = # -------------------------------------------------------------------- [testenv:look] -basepython = python3.10 deps = -r{toxinidir}/examples/look/requirements/test commands = @@ -446,7 +445,7 @@ commands = # -------------------------------------------------------------------- [testenv:asgilook] -basepython = python3.10 +basepython = python3.12 deps = -r{toxinidir}/examples/asgilook/requirements/asgilook -r{toxinidir}/examples/asgilook/requirements/test From 9b27c71e40ffafa76a160b33905281084430ef98 Mon Sep 17 00:00:00 2001 From: Mario Rivera <150161290+MRLab12@users.noreply.github.com> Date: Tue, 7 May 2024 15:30:52 -0400 Subject: [PATCH 2/2] docs(asgi-tutorial): include info on setting up logging for debugging (#2223) * Update tutorial-asgi to include info on setting up logging for debugging an application * Add Python logging docs link/add note that debugging asgi also applies to wsgi * 80 char limit / changed logging example to show use with falcon / added intersphinx * docs: update tutorial-asgi.rst --------- Co-authored-by: Vytautas Liuolia --- docs/user/tutorial-asgi.rst | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/user/tutorial-asgi.rst b/docs/user/tutorial-asgi.rst index dff2206b2..dd7c63b20 100644 --- a/docs/user/tutorial-asgi.rst +++ b/docs/user/tutorial-asgi.rst @@ -964,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? ---------