flask-request-arg


Nameflask-request-arg JSON
Version 1.0.5 PyPI version JSON
download
home_pagehttps://github.com/Martlark/flask-request-arg
SummaryEasy way to convert Flask request form, header, JSON and parameters to route arguments.
upload_time2023-10-29 07:20:13
maintainer
docs_urlNone
authorAndrew Rowe
requires_python
licenseApache Software License
keywords flask request arguments form json headers parameters
VCS
bugtrack_url
requirements Flask black
Travis-CI No Travis.
coveralls test coverage No coveralls.
            flask-request-arg
=================

The easy way to convert Flask request, form, header and request args to route parameters.

Installation
------------

pip install flask-request-arg

Introduction
------------

Handling `form` and `request` and `header` parameters in `Flask` is complex and error-prone. Common 
issues are:

 * Values need to be converted to the correct type.
 * Intricate logic used to handle defaults and missing values.
 * Request arguments and form fields are not clear from the method signature.
 * GET, PUT, POST all require different logic to get values.
 * Documentation for request and form values are not easy to generate.

`flask-request-arg` solves this issues by allowing you to use a simple decorator
to specify the argument name, type and default value.  Then any form data, JSOM
data, header or request argument is converted into a named method parameter.  POST using form 
data, GET using arguments or PUT with JSON body data all can use the same
code logic.

When using JSON data it is recommended to set the content type to "application/json". 
An attempt is made to try to convert body data to JSON if no argument is found.

Argument names
--------------

Argument names are converted into a Python acceptable variable name by removing
white space from each end and then making it lowercase and
replacing hyphen, space and other weird characters with underscore _.  If the 
name starts with a number then an underscore is prepended to the name.  Example

    @request_arg('Header-Value')

becomes:

    def route_name(header_value)

General Usage
-------------

```python

@request_arg(arg_name: str, arg_type: Any = None, arg_default=None) -> Callable:
```

* `arg_name` - the name of the argument to add as a method parameter.
* `arg_type` - the type of the argument.  All form and request args are usually strings.
* `arg_default`  - default value of the argument when not in form or request.

### Notes

 * to make an argument required do not provide an `arg_default`.
 * a `<form>` `<input>` `name` must match the `request_arg` argument name.
 * a JSON body key must match the `request_arg` argument name.
 * any request argument name must be a valid `Python` variable name.

Example
-------

To call an area of circle method with a parameter argument as in this example:

```
   /area_of_circle?radius=23.456
   
   # 1727.57755904
```

Structure your Flask route as follows:

```python
from flask_request_arg import request_arg
from flask import Response


@request_arg('radius', float)
@app.route('/area_of_circle', methods=['GET'])
def area_of_circle(radius):
    result = radius * radius * 3.14
    return Response(f"{result}", 200)
```

Forms
-----

A method that handles POST can be structured the same as a GET. Example:

```python
from flask_request_arg import request_arg
from flask import Response


@request_arg('radius', float)
@app.route('/area_of_circle', methods=['POST'])
def area_of_circle(radius):
    result = radius * radius * 3.14
    return Response(f"{result}", 200)
```

HTML example:

```html
<form action="/area_of_circle" method="post">
    <label>Radius:<input name="radius" type="number"/></label>
    <button type="submit">Get area</button>
</form>
```
NOTE: the form input name must match the `request_arg` argument name.

NOTE: request arguments and form data can be used together on the same request.

JSON Data
---------

JSON body data is treated the same as a POST or GET. Example:

```python
from flask_request_arg import request_arg
from flask import Response


@request_arg('radius', float)
@app.route('/area_of_circle', methods=['PUT'])
def area_of_circle(radius):
    result = radius * radius * 3.14
    return Response(f"{result}", 200)
```

Called like:

```javascript
fetch('/area_of_circle', {
  headers: { 'Content-Type': 'application/json' }, // tells the server we have json
  method:'PUT', 
  body: JSON.stringify({radius:45.67}), // json is sent to the server as text
})
```

NOTE: request arguments and JSON body data can be used together on the same request.

As you can see the `Flask` method code is the same for GET, PUT and POST.  So you can
do all three at once. Example:

```python
from flask_request_arg import request_arg
from flask import Response


@request_arg('radius', float)
@app.route('/area_of_circle', methods=['GET', 'PUT', 'POST'])
def area_of_circle(radius):
    result = radius * radius * 3.14
    return Response(f"{result}", 200)
```

Request arguments
-----------------

Request arguments of the type 

   `/route?argument1=value1&argument2=value2` 
   
are treated the same as `form` or `JSON` data. Example:

```python
from flask_request_arg import request_arg
from flask import Response


# /area_of_circle?radius=124.56

@request_arg('radius', float)
@app.route('/area_of_circle')
def area_of_circle(radius):
    result = radius * radius * 3.14
    return Response(f"{result}", 200)
```

Request headers
---------------

Request headers of the format:

   `header-name: values here and here` 
   
are treated the same as `form`, `parameters` or `JSON` data.



Converting values
-----------------

Use the `arg_type` parameter to specify a type conversion for the string value.

The arg_type can be any Python type.  The default is`str`.  Example:

```python
from flask_request_arg import request_arg
from flask import Response


@request_arg('radius', float)
@request_arg('number_of_circles', int)
@request_arg('name', str)
@app.route('/area_of_circle', methods=['GET'])
def area_of_circle(radius, number_of_circles, name):
    result = number_of_circles * radius * radius * 3.14
    return Response(f"{number_of_circles} of {name} is {result}", 200)
```

Custom type converters can be supplied using a `lambda`.  Example: 

```python
    @request_arg("arg_type", lambda x: x == "True")
    @app.route('/custom')
    def custom_arg_type(arg_type):
        result = "yes" if arg_type else "no"
        return Response(f"{result}", 200)
```
 
When using `bool` as an `arg_type`, a _truthy_ test will be done and 
return `True` if the value is in:

```python

    ("y", "Y", "yes", "Yes", "YES", True, "true", "True", "TRUE", 1, "1")

```

Mixing parameters
-----------------

If required, you can mix Flask request parameters with request arguments.  Example:

```python
from flask_request_arg import request_arg
from flask import Response


@request_arg('radius', float)
@app.route('/area_of_circle/<float:pi>/', methods=['GET'])
def area_of_circle(pi, radius):
    result = radius * radius * pi
    return Response(f"{result}", 200)
```


Release history
---------------

* 1.0.5 - Allow JSON coercion of body data. 
* 1.0.4 - Add argument variable name fixing
* 1.0.3 - Add header support
* 1.0.2 - Fix publish
* 1.0.1 - Use truthy values for `bool` types
* 1.0.0 - Tidy up documentation.  Proper release.
* 0.0.2 - Initial release

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Martlark/flask-request-arg",
    "name": "flask-request-arg",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "flask request arguments form json headers parameters",
    "author": "Andrew Rowe",
    "author_email": "rowe.andrew.d@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/9b/e1/f3c50373e0c826fab2d21302f1106128778d6aa88f7412345cf0b76ff31a/flask-request-arg-1.0.5.tar.gz",
    "platform": null,
    "description": "flask-request-arg\n=================\n\nThe easy way to convert Flask request, form, header and request args to route parameters.\n\nInstallation\n------------\n\npip install flask-request-arg\n\nIntroduction\n------------\n\nHandling `form` and `request` and `header` parameters in `Flask` is complex and error-prone. Common \nissues are:\n\n * Values need to be converted to the correct type.\n * Intricate logic used to handle defaults and missing values.\n * Request arguments and form fields are not clear from the method signature.\n * GET, PUT, POST all require different logic to get values.\n * Documentation for request and form values are not easy to generate.\n\n`flask-request-arg` solves this issues by allowing you to use a simple decorator\nto specify the argument name, type and default value.  Then any form data, JSOM\ndata, header or request argument is converted into a named method parameter.  POST using form \ndata, GET using arguments or PUT with JSON body data all can use the same\ncode logic.\n\nWhen using JSON data it is recommended to set the content type to \"application/json\". \nAn attempt is made to try to convert body data to JSON if no argument is found.\n\nArgument names\n--------------\n\nArgument names are converted into a Python acceptable variable name by removing\nwhite space from each end and then making it lowercase and\nreplacing hyphen, space and other weird characters with underscore _.  If the \nname starts with a number then an underscore is prepended to the name.  Example\n\n    @request_arg('Header-Value')\n\nbecomes:\n\n    def route_name(header_value)\n\nGeneral Usage\n-------------\n\n```python\n\n@request_arg(arg_name: str, arg_type: Any = None, arg_default=None) -> Callable:\n```\n\n* `arg_name` - the name of the argument to add as a method parameter.\n* `arg_type` - the type of the argument.  All form and request args are usually strings.\n* `arg_default`  - default value of the argument when not in form or request.\n\n### Notes\n\n * to make an argument required do not provide an `arg_default`.\n * a `<form>` `<input>` `name` must match the `request_arg` argument name.\n * a JSON body key must match the `request_arg` argument name.\n * any request argument name must be a valid `Python` variable name.\n\nExample\n-------\n\nTo call an area of circle method with a parameter argument as in this example:\n\n```\n   /area_of_circle?radius=23.456\n   \n   # 1727.57755904\n```\n\nStructure your Flask route as follows:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n@request_arg('radius', float)\n@app.route('/area_of_circle', methods=['GET'])\ndef area_of_circle(radius):\n    result = radius * radius * 3.14\n    return Response(f\"{result}\", 200)\n```\n\nForms\n-----\n\nA method that handles POST can be structured the same as a GET. Example:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n@request_arg('radius', float)\n@app.route('/area_of_circle', methods=['POST'])\ndef area_of_circle(radius):\n    result = radius * radius * 3.14\n    return Response(f\"{result}\", 200)\n```\n\nHTML example:\n\n```html\n<form action=\"/area_of_circle\" method=\"post\">\n    <label>Radius:<input name=\"radius\" type=\"number\"/></label>\n    <button type=\"submit\">Get area</button>\n</form>\n```\nNOTE: the form input name must match the `request_arg` argument name.\n\nNOTE: request arguments and form data can be used together on the same request.\n\nJSON Data\n---------\n\nJSON body data is treated the same as a POST or GET. Example:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n@request_arg('radius', float)\n@app.route('/area_of_circle', methods=['PUT'])\ndef area_of_circle(radius):\n    result = radius * radius * 3.14\n    return Response(f\"{result}\", 200)\n```\n\nCalled like:\n\n```javascript\nfetch('/area_of_circle', {\n  headers: { 'Content-Type': 'application/json' }, // tells the server we have json\n  method:'PUT', \n  body: JSON.stringify({radius:45.67}), // json is sent to the server as text\n})\n```\n\nNOTE: request arguments and JSON body data can be used together on the same request.\n\nAs you can see the `Flask` method code is the same for GET, PUT and POST.  So you can\ndo all three at once. Example:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n@request_arg('radius', float)\n@app.route('/area_of_circle', methods=['GET', 'PUT', 'POST'])\ndef area_of_circle(radius):\n    result = radius * radius * 3.14\n    return Response(f\"{result}\", 200)\n```\n\nRequest arguments\n-----------------\n\nRequest arguments of the type \n\n   `/route?argument1=value1&argument2=value2` \n   \nare treated the same as `form` or `JSON` data. Example:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n# /area_of_circle?radius=124.56\n\n@request_arg('radius', float)\n@app.route('/area_of_circle')\ndef area_of_circle(radius):\n    result = radius * radius * 3.14\n    return Response(f\"{result}\", 200)\n```\n\nRequest headers\n---------------\n\nRequest headers of the format:\n\n   `header-name: values here and here` \n   \nare treated the same as `form`, `parameters` or `JSON` data.\n\n\n\nConverting values\n-----------------\n\nUse the `arg_type` parameter to specify a type conversion for the string value.\n\nThe arg_type can be any Python type.  The default is`str`.  Example:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n@request_arg('radius', float)\n@request_arg('number_of_circles', int)\n@request_arg('name', str)\n@app.route('/area_of_circle', methods=['GET'])\ndef area_of_circle(radius, number_of_circles, name):\n    result = number_of_circles * radius * radius * 3.14\n    return Response(f\"{number_of_circles} of {name} is {result}\", 200)\n```\n\nCustom type converters can be supplied using a `lambda`.  Example: \n\n```python\n    @request_arg(\"arg_type\", lambda x: x == \"True\")\n    @app.route('/custom')\n    def custom_arg_type(arg_type):\n        result = \"yes\" if arg_type else \"no\"\n        return Response(f\"{result}\", 200)\n```\n \nWhen using `bool` as an `arg_type`, a _truthy_ test will be done and \nreturn `True` if the value is in:\n\n```python\n\n    (\"y\", \"Y\", \"yes\", \"Yes\", \"YES\", True, \"true\", \"True\", \"TRUE\", 1, \"1\")\n\n```\n\nMixing parameters\n-----------------\n\nIf required, you can mix Flask request parameters with request arguments.  Example:\n\n```python\nfrom flask_request_arg import request_arg\nfrom flask import Response\n\n\n@request_arg('radius', float)\n@app.route('/area_of_circle/<float:pi>/', methods=['GET'])\ndef area_of_circle(pi, radius):\n    result = radius * radius * pi\n    return Response(f\"{result}\", 200)\n```\n\n\nRelease history\n---------------\n\n* 1.0.5 - Allow JSON coercion of body data. \n* 1.0.4 - Add argument variable name fixing\n* 1.0.3 - Add header support\n* 1.0.2 - Fix publish\n* 1.0.1 - Use truthy values for `bool` types\n* 1.0.0 - Tidy up documentation.  Proper release.\n* 0.0.2 - Initial release\n",
    "bugtrack_url": null,
    "license": "Apache Software License",
    "summary": "Easy way to convert Flask request form, header, JSON and parameters to route arguments.",
    "version": "1.0.5",
    "project_urls": {
        "Download": "https://github.com/Martlark/flask-request-arg/archive/1.0.5.tar.gz",
        "Homepage": "https://github.com/Martlark/flask-request-arg"
    },
    "split_keywords": [
        "flask",
        "request",
        "arguments",
        "form",
        "json",
        "headers",
        "parameters"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "42540c44f786d721e511ecd2a90a9fcd06c2cf859da247be9e22e6d0a4a90c14",
                "md5": "6ef99a9cdf5313eb0a1b209a30c2deae",
                "sha256": "cefaf18bb94c62fa6957b936c2dce273354e4f8dae41205729b8df4488072d05"
            },
            "downloads": -1,
            "filename": "flask_request_arg-1.0.5-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6ef99a9cdf5313eb0a1b209a30c2deae",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 9415,
            "upload_time": "2023-10-29T07:20:11",
            "upload_time_iso_8601": "2023-10-29T07:20:11.655780Z",
            "url": "https://files.pythonhosted.org/packages/42/54/0c44f786d721e511ecd2a90a9fcd06c2cf859da247be9e22e6d0a4a90c14/flask_request_arg-1.0.5-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9be1f3c50373e0c826fab2d21302f1106128778d6aa88f7412345cf0b76ff31a",
                "md5": "68c435c284fe5358e36959b8719fed77",
                "sha256": "8c10f2f2b9004a3b4d328c56b60250f98a6dbcbf1e8ac9e9a243defe7828f0a2"
            },
            "downloads": -1,
            "filename": "flask-request-arg-1.0.5.tar.gz",
            "has_sig": false,
            "md5_digest": "68c435c284fe5358e36959b8719fed77",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 10591,
            "upload_time": "2023-10-29T07:20:13",
            "upload_time_iso_8601": "2023-10-29T07:20:13.108717Z",
            "url": "https://files.pythonhosted.org/packages/9b/e1/f3c50373e0c826fab2d21302f1106128778d6aa88f7412345cf0b76ff31a/flask-request-arg-1.0.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-29 07:20:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Martlark",
    "github_project": "flask-request-arg",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "Flask",
            "specs": []
        },
        {
            "name": "black",
            "specs": []
        }
    ],
    "lcname": "flask-request-arg"
}
        
Elapsed time: 0.30318s