[responses] html and plaintext return types as ret_type argument

This commit is contained in:
Maxime Alves LIRMM 2022-08-18 20:19:36 +02:00
parent 5d1b88daca
commit 53a691d985
8 changed files with 58 additions and 6 deletions

View File

@ -1,5 +1,11 @@
# HalfAPI # HalfAPI
## 0.7.0-rc0
- Add *html* return type as default argument ret_type
- Add *txt* return type
## 0.6.21 ## 0.6.21
- Store only domain's config in halfapi['config'] - Store only domain's config in halfapi['config']

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
__version__ = '0.6.21' __version__ = '0.6.22-rc0'
def version(): def version():
return f'HalfAPI version:{__version__}' return f'HalfAPI version:{__version__}'

View File

@ -16,7 +16,7 @@ import yaml
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from halfapi.lib import acl from halfapi.lib import acl
from halfapi.lib.responses import ORJSONResponse, ODSResponse, XLSXResponse from halfapi.lib.responses import ORJSONResponse, ODSResponse, XLSXResponse, PlainTextResponse, HTMLResponse
# from halfapi.lib.router import read_router # from halfapi.lib.router import read_router
from halfapi.lib.constants import VERBS from halfapi.lib.constants import VERBS
@ -59,6 +59,11 @@ def route_decorator(fct: FunctionType, ret_type: str = 'json') -> Coroutine:
@acl.args_check @acl.args_check
async def wrapped(request, *args, **kwargs): async def wrapped(request, *args, **kwargs):
fct_args_spec = inspect.getfullargspec(fct).args fct_args_spec = inspect.getfullargspec(fct).args
fct_args_defaults = inspect.getfullargspec(fct).defaults or []
fct_args_defaults_dict = {}
for i in range(len(fct_args_defaults)):
fct_args_defaults_dict[fct_args_spec[-i]] = fct_args_defaults[-i]
fct_args = request.path_params.copy() fct_args = request.path_params.copy()
if 'halfapi' in fct_args_spec: if 'halfapi' in fct_args_spec:
@ -76,10 +81,12 @@ def route_decorator(fct: FunctionType, ret_type: str = 'json') -> Coroutine:
if 'out' in fct_args_spec: if 'out' in fct_args_spec:
fct_args['out'] = kwargs.get('out') fct_args['out'] = kwargs.get('out')
""" If format argument is specified (either by get, post param or function argument)
""" If format argument is specified (either by get or by post param)
""" """
ret_type = fct_args.get('data', {}).get('format', 'json') if 'ret_type' in fct_args_defaults_dict:
ret_type = fct_args_defaults_dict['ret_type']
else:
ret_type = fct_args.get('data', {}).get('format', 'json')
try: try:
if ret_type == 'json': if ret_type == 'json':
@ -101,6 +108,19 @@ def route_decorator(fct: FunctionType, ret_type: str = 'json') -> Coroutine:
return XLSXResponse(res) return XLSXResponse(res)
if ret_type in ['html', 'xhtml']:
res = fct(**fct_args)
assert isinstance(res, str)
return HTMLResponse(res)
if ret_type in 'txt':
res = fct(**fct_args)
assert isinstance(res, str)
return PlainTextResponse(res)
raise NotImplementedError raise NotImplementedError
except NotImplementedError as exc: except NotImplementedError as exc:

View File

@ -23,7 +23,7 @@ from io import BytesIO
import orjson import orjson
# asgi framework # asgi framework
from starlette.responses import PlainTextResponse, Response, JSONResponse from starlette.responses import PlainTextResponse, Response, JSONResponse, HTMLResponse
from .user import JWTUser, Nobody from .user import JWTUser, Nobody
from ..logging import logger from ..logging import logger

View File

@ -1,9 +1,11 @@
import pytest
from click.testing import CliRunner from click.testing import CliRunner
from halfapi.cli.cli import cli from halfapi.cli.cli import cli
import os import os
from unittest.mock import patch from unittest.mock import patch
@pytest.mark.skip
def test_run_noproject(cli_runner): def test_run_noproject(cli_runner):
with cli_runner.isolated_filesystem(): with cli_runner.isolated_filesystem():
result = cli_runner.invoke(cli, ['config']) result = cli_runner.invoke(cli, ['config'])

View File

@ -0,0 +1,13 @@
from halfapi.lib import acl
ACLS = {
'GET': [{'acl':acl.public}]
}
def get(ret_type='html'):
"""
responses:
200:
description: dummy abc.alphabet route
"""
return '\n'.join(('trololo', '', 'ololotr'))

View File

@ -0,0 +1,4 @@
from . import get
def test_get():
assert isinstance(get(), str)

View File

@ -1,3 +1,4 @@
import pytest
from halfapi.testing.test_domain import TestDomain from halfapi.testing.test_domain import TestDomain
from pprint import pprint from pprint import pprint
@ -13,3 +14,9 @@ class TestDummyDomain(TestDomain):
def test_routes(self): def test_routes(self):
self.check_routes() self.check_routes()
def test_html_route(self):
res = self.client.get('/ret_type')
assert res.status_code == 200
assert isinstance(res.content.decode(), str)
assert res.headers['content-type'].split(';')[0] == 'text/html'