diff --git a/CHANGELOG.md b/CHANGELOG.md index 27df2ee..2794cdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # HalfAPI +## 0.6.19 + +- Allow file sending in multipart request (#32) +- Add python-multipart dependency + ## 0.6.18 - Fix config coming from .halfapi/config when using HALFAPI_DOMAIN_NAME environment variable diff --git a/Pipfile b/Pipfile index 2205f44..7f00c88 100644 --- a/Pipfile +++ b/Pipfile @@ -9,7 +9,6 @@ requests = "*" pytest-asyncio = "*" pylint = "*" build = "*" -#pytest-pythonpath = "*" twine = "*" pyflakes = "*" vulture = "*" @@ -27,6 +26,7 @@ schema = ">=0.7.4,<1" toml = "*" pip = "*" packaging = ">=19.0" +python-multipart = "*" [scripts] halfapi = "python -m halfapi" diff --git a/Pipfile.lock b/Pipfile.lock index 7bebd57..73d1028 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "5c65d8525f79ff0553d6d7b0d461fc1f6fd1e15bf0a7f3d38c7b280d21ee7939" + "sha256": "535499da1e4241f41f1a9f5f5509d0b9316d407e8b994455451ad56c80deffdc" }, "pipfile-spec": 6, "requires": {}, @@ -136,6 +136,13 @@ "markers": "python_full_version >= '3.6.8'", "version": "==3.0.9" }, + "python-multipart": { + "hashes": [ + "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43" + ], + "index": "pypi", + "version": "==0.0.5" + }, "pyyaml": { "hashes": [ "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", @@ -179,6 +186,14 @@ "index": "pypi", "version": "==0.7.5" }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.16.0" + }, "sniffio": { "hashes": [ "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663", @@ -432,7 +447,7 @@ "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", + "markers": "python_full_version >= '3.6.1' and python_version < '4'", "version": "==5.10.1" }, "jeepney": { @@ -641,7 +656,7 @@ "sha256:4c586de507202505346f3e32d1363eb9ed6932f0c2f63184dea88983ff4971e2", "sha256:d2bbd99c320a2532ac71ff6a3164867884357da3e3301f0240090c5d2fdac7ec" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.3'", + "markers": "python_full_version >= '3.6.3' and python_version < '4'", "version": "==12.4.4" }, "secretstorage": { @@ -665,7 +680,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "toml": { @@ -681,7 +696,7 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version < '3.11'", + "markers": "python_version >= '3.7'", "version": "==2.0.1" }, "tomlkit": { @@ -689,7 +704,7 @@ "sha256:0f4050db66fd445b885778900ce4dd9aea8c90c4721141fde0d6ade893820ef1", "sha256:71ceb10c0eefd8b8f11fe34e8a51ad07812cb1dc3de23247425fbc9ddc47b9dd" ], - "markers": "python_version >= '3.6' and python_version < '4.0'", + "markers": "python_version >= '3.6' and python_version < '4'", "version": "==0.11.0" }, "twine": { @@ -705,7 +720,7 @@ "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4.0'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.26.9" }, "virtualenv": { diff --git a/halfapi/__init__.py b/halfapi/__init__.py index 5eed838..c532caf 100644 --- a/halfapi/__init__.py +++ b/halfapi/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -__version__ = '0.6.18' +__version__ = '0.6.19' def version(): return f'HalfAPI version:{__version__}' diff --git a/halfapi/lib/acl.py b/halfapi/lib/acl.py index fd5d9ef..80b2916 100644 --- a/halfapi/lib/acl.py +++ b/halfapi/lib/acl.py @@ -56,11 +56,23 @@ def args_check(fct): data_ = dict(req.query_params) elif req.method in ['POST', 'PATCH', 'PUT', 'DELETE']: - try: - data_ = await req.json() - except JSONDecodeError as exc: - logger.debug('Posted data was not JSON') - pass + if req.scope.get('headers'): + if b'content-type' not in dict(req.scope.get('headers')): + data_ = {} + else: + content_type = dict(req.scope.get('headers')).get(b'content-type').decode().split(';')[0] + + if content_type == 'application/json': + try: + data_ = await req.json() + except JSONDecodeError as exc: + logger.debug('Posted data was not JSON') + pass + elif content_type in [ + 'multipart/form-data', 'application/x-www-form-urlencoded']: + data_ = await req.form() + else: + data_ = await req.body() def plural(array: list) -> str: return 's' if len(array) > 1 else '' @@ -69,7 +81,7 @@ def args_check(fct): args_d = req.scope.get('args') - if args_d is not None: + if args_d is not None and isinstance(data_, dict): required = args_d.get('required', set()) missing = [] @@ -90,7 +102,7 @@ def args_check(fct): if key in data_: data[key] = data_[key] else: - """ Unsafe mode, without specified arguments + """ Unsafe mode, without specified arguments, or plain text mode """ data = data_ diff --git a/setup.py b/setup.py index 05b0603..82a48b2 100755 --- a/setup.py +++ b/setup.py @@ -52,19 +52,22 @@ setup( "timing-asgi>=0.2.1,<1", "schema>=0.7.4,<1", "toml>=0.7.1,<0.8", - "packaging>=19.0" + "packaging>=19.0", + "python-multipart" ], classifiers=[ "Development Status :: 3 - Alpha", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Intended Audience :: Developers", "Topic :: Software Development :: Libraries :: Application Frameworks", + "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10" ], extras_require={ "tests":[ - "pytest", + "pytest>=7,<8", "requests", "pytest-asyncio", "pylint"