Skip to content

Commit

Permalink
Invoke view functions with kwargs instead of positional args
Browse files Browse the repository at this point in the history
Closes #429.
  • Loading branch information
jamesls committed Jul 26, 2017
1 parent c6b9650 commit 1cc9841
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 7 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ CHANGELOG
1.0.0b2
=======

Please read the `upgrade notes for 1.0.0b2
<http://chalice.readthedocs.io/en/latest/upgrading.html#v1-0-0b2>`__
for more detailed information about upgrading to this release.

Note: to install this beta version of chalice you must specify
``pip install 'chalice>=1.0.0b2,<2.0.0'`` or
use the ``--pre`` flag for pip: ``pip install --pre chalice``.

* Set env vars from config in ``chalice local``
(`#396 <https://github.com/awslabs/chalice/issues/396>`__)
* Fix edge case when building packages with optional c extensions
Expand All @@ -16,6 +24,9 @@ CHANGELOG
(`#428 <https://github.com/awslabs/chalice/pull/428>`__)
* Validate route path is not an empty string
(`#432 <https://github.com/awslabs/chalice/pull/432>`__)
* Change route code to invoke view function with kwargs instead of
positional args
(`#429 <https://github.com/awslabs/chalice/issues/429>`__)


1.0.0b1
Expand Down
6 changes: 3 additions & 3 deletions chalice/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,8 @@ def __call__(self, event, context):
http_status_code=405)
route_entry = self.routes[resource_path][http_method]
view_function = route_entry.view_function
function_args = [event['pathParameters'][name]
for name in route_entry.view_args]
function_args = {name: event['pathParameters'][name]
for name in route_entry.view_args}
self.current_request = Request(event['queryStringParameters'],
event['headers'],
event['pathParameters'],
Expand Down Expand Up @@ -631,7 +631,7 @@ def _validate_binary_response(self, request_headers, response_headers):

def _get_view_function_response(self, view_function, function_args):
try:
response = view_function(*function_args)
response = view_function(**function_args)
if not isinstance(response, Response):
response = Response(body=response)
self._validate_response(response)
Expand Down
8 changes: 4 additions & 4 deletions docs/source/topics/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ will then be passed in as arguments to your view function:
If you then go to ``https://endpoint/users/james``, then the view function
will be called as: ``users('james')``. The parameters are passed as
positional parameters based on the order they appear in the URL. The argument
names for the view function do not need to match the name of the captured
keyword parameters based on the name as they appear in the URL. The argument
names for the view function must match the name of the captured
argument:


Expand All @@ -70,8 +70,8 @@ argument:
@app.route('/a/{first}/b/{second}')
def users(first_arg, second_arg):
return {'first': first_arg, 'second': second_arg}
def users(first, second):
return {'first': first, 'second': second}
Other Request Metadata
Expand Down
40 changes: 40 additions & 0 deletions docs/source/upgrading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,46 @@ interested in the high level changes, see the
`CHANGELOG.rst <https://github.com/awslabs/chalice/blob/master/CHANGELOG.rst>`__)
file.

.. _v1-0-0b2:

1.0.0b2
-------

The url parameter names and the function argument names must match.
Previously, the routing code would use positional args ``handler(*args)``
to invoke a view function. In this version, kwargs are now used instead:
``handler(**view_args)``. For example, this code will no longer work:

.. code-block:: python
@app.route('/{a}/{b}')
def myview(first, second)
return {}
The example above must be updated to:


.. code-block:: python
@app.route('/{a}/{b}')
def myview(a, b)
return {}
Now that functions are invoked with kwargs, the order doesn't matter. You may
also write the above view function as:


.. code-block:: python
@app.route('/{a}/{b}')
def myview(b, a)
return {}
This was done to have consistent behavior with other web frameworks such as
Flask.

.. _v1-0-0b1:

1.0.0b1
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1172,3 +1172,16 @@ def test_aws_execution_env_set():
assert env['AWS_EXECUTION_ENV'] == (
'AWS_Lambda_python2.7 aws-chalice/%s' % chalice_version
)


def test_can_use_out_of_order_args():
demo = app.Chalice('demo-app')

# Note how the url params and function args are out of order.
@demo.route('/{a}/{b}', methods=['GET'])
def index(b, a):
return {'a': a, 'b': b}
event = create_event('/{a}/{b}', 'GET', {'a': 'first', 'b': 'second'})
response = demo(event, context=None)
response = json_response_body(response)
assert response == {'a': 'first', 'b': 'second'}

0 comments on commit 1cc9841

Please sign in to comment.