Skip to content

Commit

Permalink
Merge pull request #756 from timothycrosley/develop
Browse files Browse the repository at this point in the history
Release 2.4.6
  • Loading branch information
timothycrosley committed Mar 26, 2019
2 parents 9756917 + 4801e1d commit 0e305b5
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2.4.5
current_version = 2.4.6

[bumpversion:file:.env]

Expand Down
2 changes: 1 addition & 1 deletion .env
Expand Up @@ -11,7 +11,7 @@ fi

export PROJECT_NAME=$OPEN_PROJECT_NAME
export PROJECT_DIR="$PWD"
export PROJECT_VERSION="2.4.5"
export PROJECT_VERSION="2.4.6"

if [ ! -d "venv" ]; then
if ! hash pyvenv 2>/dev/null; then
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,11 @@ Ideally, within a virtual environment.
Changelog
=========

### 2.4.6 - March 25, 2019
- Fixed issue #753 - 404 not found does not respect default output format.
- Documented the `--without-cython` option in `CONTRIBUTING.md`
- Extended documentation for output formats

### 2.4.4 - March 21, 2019
- Added the ability to change the default output format for CLI endpoints both at the API and global level.
- Added the ablity to extend CLI APIs in addition to HTTP APIs issue #744.
Expand Down
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -33,6 +33,20 @@ Once you have verified that you system matches the base requirements you can sta
- If you don't have autoenv set-up, run `source .env` to set up the local environment. You will need to run this script every time you want to work on the project - though it will not cause the entire set up process to re-occur.
4. Run `test` to verify your everything is set up correctly. If the tests all pass, you have successfully set up hug for local development! If not, you can ask for help diagnosing the error [here](https://gitter.im/timothycrosley/hug).

At step 3, you can skip using autoenv and the `.env` script,
and create your development virtul environment manually instead
using e.g. [`python3 -m venv`](https://docs.python.org/3/library/venv.html)
or `mkvirtualenv` (from [virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/)).

Install dependencies by running `pip install -r requirements/release.txt`,
and optional build or development dependencies
by running `pip install -r requirements/build.txt`
or `pip install -r requirements/build.txt`.

Install Hug itself with `pip install .` or `pip install -e .` (for editable mode).
This will compile all modules with [Cython](https://cython.org/) if it's installed in the environment.
You can skip Cython compilation using `pip install --without-cython .` (this works with `-e` as well).

Making a contribution
=========
Congrats! You're now ready to make a contribution! Use the following as a guide to help you reach a successful pull-request:
Expand Down
34 changes: 32 additions & 2 deletions documentation/OUTPUT_FORMATS.md
Expand Up @@ -3,7 +3,7 @@ hug output formats

Every endpoint that is exposed through an externally facing interface will need to return data in a standard, easily understandable format.

The default output format for all hug APIs is JSON. However, you may explicitly specify a different default output_format:
The default output format for all hug APIs is JSON. However, you may explicitly specify a different default output_format for a particular API:

hug.API(__name__).http.output_format = hug.output_format.html

Expand All @@ -13,7 +13,14 @@ or:
def my_output_formatter(data, request, response):
# Custom output formatting code

Or, to specify an output_format for a specific endpoint, simply specify the output format within its router:
By default, this only applies to the output format of HTTP responses.
To change the output format of the command line interface:

@hug.default_output_format(cli=True, http=False)
def my_output_formatter(data, request, response):
# Custom output formatting code

To specify an output_format for a specific endpoint, simply specify the output format within its router:

@hug.get(output=hug.output_format.html)
def my_endpoint():
Expand Down Expand Up @@ -42,6 +49,29 @@ Finally, an output format may be a collection of different output formats that g

In this case, if the endpoint is accessed via my_endpoint.js, the output type will be JSON; however if it's accessed via my_endoint.html, the output type will be HTML.

You can also change the default output format globally for all APIs with either:

@hug.default_output_format(apply_globally=True, cli=True, http=True)
def my_output_formatter(data, request, response):
# Custom output formatting code

or:

hug.defaults.output_format = hug.output_format.html # for HTTP
hug.defaults.cli_output_format = hug.output_format.html # for the CLI

Note that when extending APIs, changing the default output format globally must be done before importing the modules of any of the sub-APIs:

hug.defaults.cli_output_format = hug.output_format.html

from my_app import my_sub_api

@hug.extend_api()
def extended():
return [my_sub_api]



Built-in hug output formats
===================

Expand Down
2 changes: 1 addition & 1 deletion hug/_version.py
Expand Up @@ -21,4 +21,4 @@
"""
from __future__ import absolute_import

current = "2.4.5"
current = "2.4.6"
11 changes: 9 additions & 2 deletions hug/api.py
Expand Up @@ -305,9 +305,16 @@ def handle_404(request, response, *args, **kwargs):
"Here's a definition of the API to help you get going :)")
to_return['documentation'] = self.documentation(base_url, self.determine_version(request, False),
prefix=url_prefix)
response.data = hug.output_format.json(to_return, indent=4, separators=(',', ': '))

if self.output_format == hug.output_format.json:
response.data = hug.output_format.json(to_return, indent=4, separators=(',', ': '))
response.content_type = 'application/json; charset=utf-8'
else:
response.data = self.output_format(to_return)
response.content_type = self.output_format.content_type

response.status = falcon.HTTP_NOT_FOUND
response.content_type = 'application/json; charset=utf-8'

handle_404.interface = True
return handle_404

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -75,7 +75,7 @@ def list_modules(dirname):

setup(
name='hug',
version='2.4.5',
version='2.4.6',
description='A Python framework that makes developing APIs '
'as simple as possible, but no simpler.',
long_description=long_description,
Expand Down
16 changes: 9 additions & 7 deletions tests/test_decorators.py
Expand Up @@ -307,30 +307,32 @@ def accepts_get_and_post():
assert 'method not allowed' in hug.test.trace(api, 'accepts_get_and_post').status.lower()


def test_not_found():
def test_not_found(hug_api):
"""Test to ensure the not_found decorator correctly routes 404s to the correct handler"""
@hug.not_found()
@hug.not_found(api=hug_api)
def not_found_handler():
return "Not Found"

result = hug.test.get(api, '/does_not_exist/yet')
result = hug.test.get(hug_api, '/does_not_exist/yet')
assert result.data == "Not Found"
assert result.status == falcon.HTTP_NOT_FOUND

@hug.not_found(versions=10) # noqa
@hug.not_found(versions=10, api=hug_api) # noqa
def not_found_handler(response):
response.status = falcon.HTTP_OK
return {'look': 'elsewhere'}

result = hug.test.get(api, '/v10/does_not_exist/yet')
result = hug.test.get(hug_api, '/v10/does_not_exist/yet')
assert result.data == {'look': 'elsewhere'}
assert result.status == falcon.HTTP_OK

result = hug.test.get(api, '/does_not_exist/yet')
result = hug.test.get(hug_api, '/does_not_exist/yet')
assert result.data == "Not Found"
assert result.status == falcon.HTTP_NOT_FOUND

del api.http._not_found_handlers
hug_api.http.output_format = hug.output_format.text
result = hug.test.get(hug_api, '/v10/does_not_exist/yet')
assert result.data == "{'look': 'elsewhere'}"


def test_not_found_with_extended_api():
Expand Down

0 comments on commit 0e305b5

Please sign in to comment.