Repository: falconry/falcon

Issue:
Hook after params attribute is missing 
Hi

```python
def do_before(req, resp, resource, params):
	# here params is available

def do_after(req, resp, resource, params):
	# here params is not available

```

How can I access the params?



Discussion:
Hi @bronte2k7 !
Currently, the framework is designed in a way that "after" hooks do not have access to `params`, and the signature they should follow is [`func(req, resp, resource)`](https://falcon.readthedocs.io/en/stable/api/hooks.html#falcon.after) (plus any additional args/kwargs you can pass via `falcon.after`).

I see though that documentation for the `*args` parameter in `falcon.after` does mention `params`, but that's most likely a copy-paste mistake that we'll try to rectify.

The idea of _after_ hooks is that they are thought to be used for post-processing the response, where access to `params` is seldom needed. See also the [`process_response` middleware method](https://falcon.readthedocs.io/en/stable/api/middleware.html#middleware).

However, if you do happen to need access to `params`, or pass any other custom data along the request-response cycle, you can also use [`req.context`](https://falcon.readthedocs.io/en/stable/api/request_and_response_wsgi.html#falcon.Request.context) and/or [`resp.context`](https://falcon.readthedocs.io/en/stable/api/request_and_response_wsgi.html#falcon.Response.context) for that purpose.

For instance:
```python
import falcon


def do_before(req, resp, resource, params):
    if params.get('vegetable') == 'cucumber':
        colour = 'green'
    elif params.get('vegetable') == 'tomato':
        colour = 'red'
    else:
        colour = None

    resp.context.colour = params['colour'] = colour


def do_after(req, resp, resource):
    if resp.context.colour:
        resp.set_header('X-Colour', resp.context.colour)


class Vegetables:
    @falcon.before(do_before)
    @falcon.after(do_after)
    def on_get(self, req, resp, vegetable, colour):
        resp.media = {'vegetable': vegetable, 'colour': colour}


app = falcon.App()
app.add_route('/vegetables/{vegetable}', Vegetables())
```

See also: [How can I pass data from a hook to a responder, and between hooks?](https://falcon.readthedocs.io/en/stable/user/faq.html#how-can-i-pass-data-from-a-hook-to-a-responder-and-between-hooks)
Thanks for the detailed answer. Using context is a great idea)))

Resolving patch:
diff --git a/falcon/hooks.py b/falcon/hooks.py
--- a/falcon/hooks.py
+++ b/falcon/hooks.py
@@ -119,8 +119,8 @@ def after(action, *args, is_async=False, **kwargs):
             request
 
         *args: Any additional arguments will be passed to *action* in the
-            order given, immediately following the *req*, *resp*, *resource*,
-            and *params* arguments.
+            order given, immediately following the *req*, *resp* and *resource*
+            arguments.
 
     Keyword Args:
         is_async (bool): Set to ``True`` for ASGI apps to provide a hint that


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -51,8 +51,8 @@ jobs:
           - python-version: pypy3
             os: ubuntu-20.04
             toxenv: pypy3
-          - python-version: 3.5.2
-            os: ubuntu-16.04
+          - python-version: 3.5
+            os: ubuntu-20.04
             toxenv: py35
           - python-version: 3.6
             os: ubuntu-20.04
@@ -91,23 +91,9 @@ jobs:
 
       - name: Set up Python
         uses: actions/setup-python@v2.1.4
-        if: ${{ matrix.toxenv != 'py35' }}
         with:
           python-version: ${{ matrix.python-version }}
 
-      - name: Set up Python 3.8
-        uses: actions/setup-python@v2.1.4
-        if: ${{ matrix.toxenv == 'py35' }}
-        with:
-          python-version: 3.8
-
-      - name: Set up Python 3.5.2
-        if: ${{ matrix.toxenv == 'py35' }}
-        run: |
-          sudo apt-get update
-          sudo apt-get install -y build-essential curl python3.5 python3.5-dev
-          python3.5 --version
-
       - name: Install smoke test dependencies
         if: ${{ matrix.toxenv == 'py38_smoke' || matrix.toxenv == 'py38_smoke_cython' }}
         run: |
@@ -121,7 +107,7 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install coverage tox
+          pip install -U coverage setuptools tox wheel
           python --version
           pip --version
           tox --version