Repository: greyli/apiflask
Pull request #29 (2021-04-20 06:33:23)

Rename abort_json to abort
Checklist:

- [x] Update source
- [x] Update docs
- [x] Update examples
- [x] Update changlog


Patch:
diff --git a/CHANGES.md b/CHANGES.md
index 189cb3d..ffa996c 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -33,6 +33,7 @@ and `@iniput(examples=...)` ([pull #23][pull_23]).
 `tag` parameter now only accept string value ([pull #26][pull_26]).
 - Add new configuration variable `OPENAPI_VERSION` to set the version of OAS
 ([pull #27][pull_27]).
+- Rename `abort_json()` to `abort()` ([pull #29][pull_29]).
 
 [pull_3]: https://github.com/greyli/apiflask/pull/3
 [pull_12]: https://github.com/greyli/apiflask/pull/12
@@ -40,6 +41,7 @@ and `@iniput(examples=...)` ([pull #23][pull_23]).
 [pull_23]: https://github.com/greyli/apiflask/pull/23
 [pull_26]: https://github.com/greyli/apiflask/pull/26
 [pull_27]: https://github.com/greyli/apiflask/pull/27
+[pull_29]: https://github.com/greyli/apiflask/pull/29
 
 ## Version 0.3.0
 Released: 2021/3/31
diff --git a/README.md b/README.md
index da5578f..fff166d 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ For Windows:
 ## Example
 
 ```python
-from apiflask import APIFlask, Schema, input, output, abort_json
+from apiflask import APIFlask, Schema, input, output, abort
 from apiflask.fields import Integer, String
 from apiflask.validators import Length, OneOf
 
@@ -94,7 +94,7 @@ def say_hello():
 @output(PetOutSchema)
 def get_pet(pet_id):
     if pet_id > len(pets) - 1:
-        abort_json(404)
+        abort(404)
     # you can also return an ORM model class instance directly
     return pets[pet_id]
 
@@ -105,7 +105,7 @@ def get_pet(pet_id):
 def update_pet(pet_id, data):
     # the parsed input data (dict) will be injected into the view function
     if pet_id > len(pets) - 1:
-        abort_json(404)
+        abort(404)
     data['id'] = pet_id
     pets[pet_id] = data
     return pets[pet_id]
@@ -131,10 +131,11 @@ For a more complete example, see [/examples](https://github.com/greyli/apiflask/
 
 ## Relationship with Flask
 
-APIFlask is a thin wrapper on top of Flask, you only need to remember two differences:
+APIFlask is a thin wrapper on top of Flask, you only need to remember three differences:
 
 - When creating an application instance, use `APIFlask` instead of `Flask`.
 - When creating a blueprint instance, use `APIBlueprint` instead of `Blueprint`.
+- The `abort()` function from APIFlask (`apiflask.abort`) returns JSON error response.
 
 For a minimal Flask application:
 
diff --git a/apiflask/__init__.py b/apiflask/__init__.py
index 064249d..1ba6560 100644
--- a/apiflask/__init__.py
+++ b/apiflask/__init__.py
@@ -5,7 +5,7 @@ from .decorators import input
 from .decorators import output
 from .decorators import doc
 from .decorators import auth_required
-from .exceptions import abort_json
+from .exceptions import abort
 from .exceptions import HTTPError
 from .schemas import Schema
 from .security import HTTPBasicAuth
diff --git a/apiflask/decorators.py b/apiflask/decorators.py
index 1eb7c06..259d0be 100644
--- a/apiflask/decorators.py
+++ b/apiflask/decorators.py
@@ -93,6 +93,9 @@ def auth_required(
         roles: Similar to `role` but accepts a list of role names.
         optional: To allow the view to execute even the authentication information
             is not included with the request, in which case `auth.current_user` will be `None`.
+
+    *Version changed: 0.4.0*
+    - Add parameter `roles`.
     """
     _roles = None
     if role is not None:
@@ -169,6 +172,9 @@ def input(
                     'value': {'name': 'bar', 'id': 2}
                 },
             }
+
+    *Version changed: 0.4.0*
+    - Add parameter `examples`.
     """
     if isinstance(schema, ABCMapping):
         schema = _generate_schema_from_mapping(schema, schema_name)
@@ -251,6 +257,9 @@ def output(
                 },
             }
             ```
+
+    *Version changed: 0.4.0*
+    - Add parameter `examples`.
     """
     if schema == {}:
         schema = EmptySchema
@@ -347,10 +356,12 @@ def doc(
         deprecated: Flag this endpoint as deprecated in API docs. Defaults to `False`.
         hide: Hide this endpoint in API docs. Defaults to `False`.
 
-    *Version changed: 0.3.0*
+    *Version changed: 0.4.0*
+    - Add parameter `tag`.
 
+    *Version changed: 0.3.0*
     - Change the default value of `deprecated` from `None` to `False`.
-    - Rename argument `tags` to `tag`.
+    - Rename parameter `tags` to `tag`.
 
     *Version added: 0.2.0*
     """
diff --git a/apiflask/exceptions.py b/apiflask/exceptions.py
index 9804cbc..b162a0e 100644
--- a/apiflask/exceptions.py
+++ b/apiflask/exceptions.py
@@ -68,7 +68,7 @@ class ValidationError(HTTPError):
     pass
 
 
-def abort_json(
+def abort(
     status_code: int,
     message: Optional[str] = None,
     detail: Optional[Any] = None,
@@ -80,7 +80,7 @@ def abort_json(
     Examples:
 
     ```python
-    from apiflask import APIFlask, abort_json
+    from apiflask import APIFlask, abort
     from flask import escape
 
     app = APIFlask(__name__)
@@ -88,12 +88,12 @@ def abort_json(
     @app.get('/<name>')
     def hello(name):
         if name == 'Foo':
-            abort_json(404, 'This man is missing.')
+            abort(404, 'This man is missing.')
         return f'Hello, escape{name}'!
     ```
 
-    P.S. When `app.json_errors` is `True` (default), Flask's `abort` will also return
-    JSON error response.
+    P.S. When `app.json_errors` is `True` (default), Flask's `flask.abort` will also
+    return JSON error response.
 
     Arguments:
         status_code: The status code of the error (4XX and 5xx).
@@ -103,6 +103,9 @@ def abort_json(
             provided addition information such as custom error code, documentation
             URL, etc.
         headers: A dict of headers used in error response.
+
+    *Version changed: 0.4.0*
+    - Rename the function name from `abort_json` to `abort`.
     """
     raise HTTPError(status_code, message, detail, headers)
 
diff --git a/docs/alterinatives.md b/docs/alterinatives.md
deleted file mode 100644
index 5b5e719..0000000
--- a/docs/alterinatives.md
+++ /dev/null
@@ -1,1 +0,0 @@
-# Alterinatives and Inspirations
diff --git a/docs/migrating.md b/docs/migrating.md
index 221f2de..5a460f4 100644
--- a/docs/migrating.md
+++ b/docs/migrating.md
@@ -77,14 +77,13 @@ from apiflask import APIFlask, APIBlueprint
 from flask import request, escape, render_template, g, session, url_for
 ```
 
-### JSON errors
+### APIFlask's `abort()` vs Flask's `abort()`
 
-When you change the base class to `APIFlask`, all the error responses will
-automatically convert to JSON format. For example:
+APIFlask's `abort()` function will return a JSON error response while Flask's `abort()`
+returns an HTML error page:
 
 ```python
-from apiflask import APIFlask
-from flask import abort
+from apiflask import APIFlask, abort
 
 app = APIFlask(__name__)
 
@@ -93,8 +92,7 @@ def foo():
     abort(404)
 ```
 
-In the example above, when theuser visit `/foo`, the `abort(400)` will return a JSON
-response instead of an HTML error page:
+In the example above, when the user visit `/foo`, the response body will be:
 
 ```json
 {
@@ -104,7 +102,30 @@ response instead of an HTML error page:
 }
 ```
 
-If you want to disable this behavior, just set `json_errors` to `False`:
+You can use `message` and `detail` parameter to pass error message and detailed
+information in the `abort()` function.
+
+!!! warning
+    The function `abort_json()` was renamed to `abort()` in the
+    [version 0.4.0](/changelog/#version-040).
+
+### JSON errors and mix the use of `flask.abort()` and `apiflask.abort()`
+
+When you change the base application class to `APIFlask`, all the error responses
+will automatically convert to JSON format even if you use Flask's `abort()` function:
+
+```python
+from apiflask import APIFlask
+from flask import abort
+
+app = APIFlask(__name__)
+
+@app.get('/foo')
+def foo():
+    abort(404)
+```
+
+If you want to disable this behavior, just set `json_errors` parameter to `False`:
 
 ```python hl_lines="3"
 from apiflask import APIFlask
@@ -112,11 +133,18 @@ from apiflask import APIFlask
 app = APIFlask(__name__, json_errors=False)
 ```
 
-Now you can still use `abort_json` from `apiflask` package to return a JSON error
-response:
+Now you can still use `abort` from `apiflask` package to return a JSON error
+response. To mix the use of `flask.abort` and `apiflask.abort`, you will need to import one
+of them with different name:
 
-```python hl_lines="3"
-from apiflask import APIFlask, abort_json
+```python
+from apiflask import abort as abort_json
+```
+
+Here is a full example:
+
+```python hl_lines="1 14"
+from apiflask import APIFlask, abort as abort_json
 from flask import abort
 
 app = APIFlask(__name__, json_errors=False)
@@ -132,10 +160,6 @@ def bar():
     abort_json(404)
 ```
 
-!!! tip
-    You can use `message` and `detail` keyword to pass error message and detailed
-    information in `abort_json()` function.
-
 ### The return values of view function
 
 When you added a `@output` decorator for your view function, notice the
diff --git a/docs/openapi.md b/docs/openapi.md
index d8d5704..c452563 100644
--- a/docs/openapi.md
+++ b/docs/openapi.md
@@ -1,1 +1,1 @@
-# OpenAPI Suppport
+# OpenAPI Generating
diff --git a/docs/response.md b/docs/response.md
new file mode 100644
index 0000000..5c1671e
--- /dev/null
+++ b/docs/response.md
@@ -0,0 +1,1 @@
+# Response Formatting
diff --git a/docs/schema.md b/docs/schema.md
index 0477b31..d9d0f4e 100644
--- a/docs/schema.md
+++ b/docs/schema.md
@@ -1,1 +1,1 @@
-# Schema and Fields
+# Schema, Fields and Validators
diff --git a/docs/security.md b/docs/security.md
index 8dbb2f9..9c8a9e1 100644
--- a/docs/security.md
+++ b/docs/security.md
@@ -1,1 +1,1 @@
-# Security
+# Authentication
diff --git a/docs/usage.md b/docs/usage.md
index c6c93be..06c0ad7 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -693,21 +693,21 @@ of authentication support will be added soon).
 
 [_flask-httpauth]: https://flask-httpauth.readthedocs.io/ 
 
-## Use `abort_json()` to return an error response
+## Use `abort()` to return an error response
 
-Similar to Flask's `abort`, but `abort_json` from APIFlask will return a JSON response.
+Similar to Flask's `abort`, but `abort` from APIFlask will return a JSON response.
 
 Example:
 
 ```python hl_lines="1 8"
-from apiflask import APIFlask, abort_json
+from apiflask import APIFlask, abort
 
 app = APIFlask(__name__)
 
 @app.get('/<name>')
 def hello(name):
     if name == 'Foo':
-        abort_json(404, 'This man is missing.')
+        abort(404, 'This man is missing.')
     return {'hello': name}
 ```
 
@@ -729,7 +729,7 @@ def hello(name):
     return {'hello': name}
 ```
 
-The `abort_json()` and `HTTPError` accept the following arguments:
+The `abort()` and `HTTPError` accept the following arguments:
 
 - `status_code`: The status code of the error (4XX and 5xx).
 - `message`: The simple description of the error. If not provided,
@@ -739,6 +739,10 @@ The `abort_json()` and `HTTPError` accept the following arguments:
     URL, etc.
 - `headers`: A dict of headers used in the error response.
 
+!!! warning
+    The function `abort_json()` was renamed to `abort()` in
+    the [version 0.4.0](/changelog/#version-040).
+
 ## Overview of `apiflask` package
 
 In the end, let's unpack the whole `apiflask` package to check out what it shipped with:
@@ -749,9 +753,8 @@ In the end, let's unpack the whole `apiflask` package to check out what it shipp
 - `@output`: A decorator used to format the response.
 - `@auth_required`: A decorator used to protect a view from unauthenticated users.
 - `@doc`: A decorator used to set up the OpenAPI spec for view functions.
-- `abort_json()`: A function used to abort the request handling process and return an error response. The
-    JSON version of Flask's `abort()` function.
-- `HTTPError`: An exception used to return error response (used by `abort_json()`).
+- `abort()`: A function used to abort the request handling process and return an error response. The JSON version of Flask's `flask.abort()` function.
+- `HTTPError`: An exception used to return error response (used by `abort()`).
 - `HTTPBasicAuth`: A class used to create an auth instance.
 - `HTTPTokenAuth`: A class used to create an auth instance.
 - `Schema`: A base class for resource schemas (Will be a wrapper for Marshmallow's `Schema`).
diff --git a/examples/app.py b/examples/app.py
index 50f7905..fd6a6a9 100644
--- a/examples/app.py
+++ b/examples/app.py
@@ -1,4 +1,4 @@
-from apiflask import APIFlask, Schema, input, output, abort_json
+from apiflask import APIFlask, Schema, input, output, abort
 from apiflask.fields import Integer, String
 from apiflask.validators import Length, OneOf
 from apiflask.schemas import EmptySchema
@@ -44,7 +44,7 @@ def say_hello():
 @output(PetOutSchema)
 def get_pet(pet_id):
     if pet_id > len(pets) - 1:
-        abort_json(404)
+        abort(404)
     return pets[pet_id]
 
 
@@ -69,7 +69,7 @@ def create_pet(data):
 @output(PetOutSchema)
 def update_pet(pet_id, data):
     if pet_id > len(pets) - 1:
-        abort_json(404)
+        abort(404)
     data['id'] = pet_id
     pets[pet_id] = data
     return pets[pet_id]
@@ -80,7 +80,7 @@ def update_pet(pet_id, data):
 @output(PetOutSchema)
 def partial_update_pet(pet_id, data):
     if pet_id > len(pets) - 1:
-        abort_json(404)
+        abort(404)
     for attr, value in data.items():
         pets[pet_id][attr] = value
     return pets[pet_id]
@@ -90,6 +90,6 @@ def partial_update_pet(pet_id, data):
 @output(EmptySchema, 204)
 def delete_pet(pet_id):
     if pet_id > len(pets) - 1:
-        abort_json(404)
+        abort(404)
     pets.pop(pet_id)
     return ''


Test patch:
diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py
index 5647de2..c956acf 100644
--- a/tests/test_exceptions.py
+++ b/tests/test_exceptions.py
@@ -1,6 +1,6 @@
 import pytest
 
-from apiflask.exceptions import abort_json
+from apiflask.exceptions import abort
 from apiflask.exceptions import HTTPError
 from apiflask.exceptions import default_error_handler
 from apiflask.utils import get_reason_phrase
@@ -37,10 +37,10 @@ def test_httperror(app, client, kwargs):
     {'message': 'missing', 'detail': {'location': 'query'}},
     {'message': 'missing', 'detail': {'location': 'query'}, 'headers': {'X-BAR': 'foo'}}
 ])
-def test_abort_json(app, client, kwargs):
+def test_abort(app, client, kwargs):
     @app.get('/bar')
     def bar():
-        abort_json(404, **kwargs)
+        abort(404, **kwargs)
 
     rv = client.get('/bar')
     assert rv.status_code == 404
@@ -90,7 +90,7 @@ def test_default_error_handler(kwargs):
 
 def test_invalid_error_status_code():
     with pytest.raises(LookupError):
-        abort_json(200)
+        abort(200)
 
     with pytest.raises(LookupError):
         raise HTTPError(204)