From 061151ccebb1b3735fae311c2e8f9723a9300875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sat, 24 Jun 2017 23:57:53 +0200 Subject: [PATCH 4/5] jsonresponse: remove unused serializers from to_json decorator (#17175) --- passerelle/apps/bdp/views.py | 8 ++-- passerelle/apps/choosit/views.py | 8 ++-- passerelle/apps/clicrdv/views.py | 22 +++++----- passerelle/apps/csvdatasource/views.py | 4 +- passerelle/contrib/agoraplus/views.py | 26 +++++------ passerelle/contrib/fake_family/views.py | 4 +- passerelle/contrib/meyzieu_newsletters/views.py | 12 ++--- passerelle/contrib/solis_apa/views.py | 8 ++-- passerelle/contrib/stub_invoices/views.py | 16 +++---- passerelle/contrib/teamnet_axel/views.py | 10 ++--- passerelle/utils/jsonresponse.py | 58 +++---------------------- passerelle/views.py | 3 +- tests/test_jsonresponse.py | 37 +++++----------- 13 files changed, 78 insertions(+), 138 deletions(-) diff --git a/passerelle/apps/bdp/views.py b/passerelle/apps/bdp/views.py index ee9058e..3adc273 100644 --- a/passerelle/apps/bdp/views.py +++ b/passerelle/apps/bdp/views.py @@ -16,7 +16,7 @@ class ResourcesView(View, SingleObjectMixin): model = Bdp @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): text_key = request.GET.get('text_key') id_key = request.GET.get('id_key') @@ -29,7 +29,7 @@ class ResourcesView(View, SingleObjectMixin): r['text'] = r[text_key] elif 'text' not in r: r['text'] = r['id'] - return resources + return {'data': resources} class PostAdherentView(View, SingleObjectMixin): @@ -39,7 +39,7 @@ class PostAdherentView(View, SingleObjectMixin): raise Http404 @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def post(self, request, *args, **kwargs): data = json.loads(request.body) # JSON w.c.s. formdata date_de_naissance = data['fields'].get('date_de_naissance') @@ -61,7 +61,7 @@ class PostAdherentView(View, SingleObjectMixin): 'bibliotheque': {'id': bibliotheque_id}, 'abonnements': abonnements, } - return self.get_object().post_api('adherents', adherent) + return {'data': self.get_object().post_api('adherents', adherent)} class BdpDetailView(DetailView): diff --git a/passerelle/apps/choosit/views.py b/passerelle/apps/choosit/views.py index daa5432..cda5a58 100644 --- a/passerelle/apps/choosit/views.py +++ b/passerelle/apps/choosit/views.py @@ -51,17 +51,17 @@ class ChoositRegisterView(View, SingleObjectMixin): def dispatch(self, request, *args, **kwargs): return super(ChoositRegisterView, self).dispatch(request, *args, **kwargs) - @utils.to_json('api') + @utils.to_json() @method_decorator(csrf_exempt) def get(self, request, *args, **kwargs): user = request.GET.get('user') assert user, 'missing user parameter' - return self.get_object().get_list(user) + return {'data': self.get_object().get_list(user)} - @utils.to_json('api') + @utils.to_json() def post(self, request, *args, **kwargs): user = request.GET.get('user') assert user, 'missing user parameter' data = json.loads(request.body) assert isinstance(data, list), 'body must be a JSON list' - return self.get_object().post(user, data) + return {'data': self.get_object().post(user, data)} diff --git a/passerelle/apps/clicrdv/views.py b/passerelle/apps/clicrdv/views.py index d29073d..7f5e132 100644 --- a/passerelle/apps/clicrdv/views.py +++ b/passerelle/apps/clicrdv/views.py @@ -19,9 +19,9 @@ class DateTimesView(View, SingleObjectMixin): """ model = ClicRdv - @utils.to_json('api') + @utils.to_json() def get(self, request, intervention_id, *args, **kwargs): - return self.get_object().get_datetimes(intervention_id) + return {'data': self.get_object().get_datetimes(intervention_id)} class DatesView(View, SingleObjectMixin): @@ -34,9 +34,9 @@ class DatesView(View, SingleObjectMixin): """ model = ClicRdv - @utils.to_json('api') + @utils.to_json() def get(self, request, intervention_id, *args, **kwargs): - return self.get_object().get_dates(intervention_id) + return {'data': self.get_object().get_dates(intervention_id)} class TimesView(View, SingleObjectMixin): @@ -49,9 +49,9 @@ class TimesView(View, SingleObjectMixin): """ model = ClicRdv - @utils.to_json('api') + @utils.to_json() def get(self, request, intervention_id, date, *args, **kwargs): - return self.get_object().get_times(intervention_id, date) + return {'data': self.get_object().get_times(intervention_id, date)} class CreateAppointmentView(View, SingleObjectMixin): @@ -81,15 +81,15 @@ class CreateAppointmentView(View, SingleObjectMixin): model = ClicRdv @utils.protected_api('can_manage_appointment') - @utils.to_json('api') + @utils.to_json() def post(self, request, intervention_id=None, *args, **kwargs): if intervention_id is None: intervention_id = self.request.GET.get('intervention') data = json.loads(request.body) - return self.get_object().create_appointment( + return {'data': self.get_object().create_appointment( intervention_id, self.request.GET.get('websource'), - data) + data)} class CancelAppointmentView(View, SingleObjectMixin): @@ -102,6 +102,6 @@ class CancelAppointmentView(View, SingleObjectMixin): model = ClicRdv @utils.protected_api('can_manage_appointment') - @utils.to_json('api') + @utils.to_json() def get(self, request, appointment_id, *args, **kwargs): - return self.get_object().cancel(appointment_id) + return {'data': self.get_object().cancel(appointment_id)} diff --git a/passerelle/apps/csvdatasource/views.py b/passerelle/apps/csvdatasource/views.py index 46fad50..1468401 100644 --- a/passerelle/apps/csvdatasource/views.py +++ b/passerelle/apps/csvdatasource/views.py @@ -68,11 +68,11 @@ class CsvDataView(View, SingleObjectMixin): @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): obj = self.get_object() filters = self._filters_builder(request) - return obj.get_data(filters) + return {'data': obj.get_data(filters)} class NewQueryView(CreateView): diff --git a/passerelle/contrib/agoraplus/views.py b/passerelle/contrib/agoraplus/views.py index fe4e2d5..b48b6e2 100644 --- a/passerelle/contrib/agoraplus/views.py +++ b/passerelle/contrib/agoraplus/views.py @@ -115,13 +115,13 @@ class DetailView(GenericDetailView): def get_data(self, request, *args, **kwargs): raise NotImplementedError - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access') def get(self, request, *args, **kwargs): self.object = self.get_object() self.set_user_from_request(request) self.family = None - return self.get_data(request, *args, **kwargs) + return {'data': self.get_data(request, *args, **kwargs)} class PingView(DetailView): @@ -212,7 +212,7 @@ class AuthView(DetailView): class LinkView(GenericDetailView): model = AgoraPlus - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access') def get(self, request, *args, **kwargs): agoraplus = self.get_object() @@ -237,13 +237,13 @@ class LinkView(GenericDetailView): name_id=name_id, defaults={'login': login, 'password': password}) logger.info('link created: NameID:%r with Agora login:%r', name_id, login) - return True + return {'data': True} class UnlinkView(GenericDetailView): model = AgoraPlus - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access') def get(self, request, *args, **kwargs): agoraplus = self.get_object() @@ -252,7 +252,7 @@ class UnlinkView(GenericDetailView): name_id = request.GET['NameID'] provision_roles(name_id, 'DELETE') AgoraPlusLink.objects.filter(resource=agoraplus, name_id=name_id).delete() - return True + return {'data': True} class FamilyView(DetailView): @@ -346,7 +346,7 @@ class SasView(DetailView): def post_data(self, name_id, formdata): raise NotImplementedError - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access_sas') def post(self, request, *args, **kwargs): self.object = self.get_object() @@ -356,7 +356,7 @@ class SasView(DetailView): name_id = formdata.get('NameID') if not name_id: raise AgoraAPIError('missing NameID parameter') - return self.post_data(name_id, formdata) + return {'data': self.post_data(name_id, formdata)} class SasFamilyView(SasView): @@ -459,14 +459,14 @@ class PostFormdataView(DetailView): def post_data(self, formdata): raise NotImplementedError - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access_sas') def post(self, request, *args, **kwargs): self.object = self.get_object() self.set_user_from_request(request) data = json.loads(request.body) formdata = Formdata(data) - return self.post_data(formdata) + return {'data': self.post_data(formdata)} class IncomesDeclarationView(PostFormdataView): @@ -525,13 +525,13 @@ class InvoicePayView(DetailView): def dispatch(self, *args, **kwargs): return super(InvoicePayView, self).dispatch(*args, **kwargs) - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access') def post(self, request, *args, **kwargs): self.object = self.get_object() data = json.loads(request.body) - return self.object.pay_invoice(kwargs['invoice_id'], data['transaction_id'], - data['transaction_date']) + return {'data': self.object.pay_invoice(kwargs['invoice_id'], data['transaction_id'], + data['transaction_date'])} class InvoiceView(DetailView): diff --git a/passerelle/contrib/fake_family/views.py b/passerelle/contrib/fake_family/views.py index b4b14b0..b903ad6 100644 --- a/passerelle/contrib/fake_family/views.py +++ b/passerelle/contrib/fake_family/views.py @@ -45,10 +45,10 @@ class DetailView(GenericDetailView): def get_data(self, request, *args, **kwargs): raise NotImplementedError - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): self.resource = self.get_object() - return self.get_data(request, *args, **kwargs) + return {'data': self.get_data(request, *args, **kwargs)} class LinkView(DetailView): diff --git a/passerelle/contrib/meyzieu_newsletters/views.py b/passerelle/contrib/meyzieu_newsletters/views.py index f993a18..9058d79 100644 --- a/passerelle/contrib/meyzieu_newsletters/views.py +++ b/passerelle/contrib/meyzieu_newsletters/views.py @@ -36,9 +36,9 @@ class DetailView(GenericDetailView): raise NotImplementedError @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): - return self.get_data(request, *args, **kwargs) + return {'data': self.get_data(request, *args, **kwargs)} class NewslettersTypesView(DetailView): @@ -54,7 +54,7 @@ class NewslettersSubscriptionsView(DetailView): return super(NewslettersSubscriptionsView, self).dispatch(*args, **kwargs) @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def delete(self, request, *args, **kwargs): email = request.GET.get('email') assert email, 'missing email parameter' @@ -62,15 +62,15 @@ class NewslettersSubscriptionsView(DetailView): subscriptions = obj.get_subscriptions(email) for sub in subscriptions: sub['transports'] = [] - return obj.set_subscriptions(email, subscriptions) + return {'data': obj.set_subscriptions(email, subscriptions)} @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def post(self, request, *args, **kwargs): email = request.GET.get('email') assert email, 'missing email parameter' data = json.loads(request.body) - return self.get_object().set_subscriptions(email, data) + return {'data': self.get_object().set_subscriptions(email, data)} def get_data(self, request, *args, **kwargs): return self.get_object().get_subscriptions(request.GET.get('email')) diff --git a/passerelle/contrib/solis_apa/views.py b/passerelle/contrib/solis_apa/views.py index 5b069a6..b580297 100644 --- a/passerelle/contrib/solis_apa/views.py +++ b/passerelle/contrib/solis_apa/views.py @@ -41,9 +41,9 @@ class DetailView(GenericDetailView): raise NotImplementedError @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): - return self.get_data(request, *args, **kwargs) + return {'data': self.get_data(request, *args, **kwargs)} def _get_params(self, request, *params): return [ request.GET.get(item, None) for item in params] @@ -106,7 +106,7 @@ class IntegrationView(View, SingleObjectMixin): return super(IntegrationView, self).dispatch(request, *args, **kwargs) @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def post(self, request, *args, **kwargs): data = request.body - return self.get_object().import_flow(data) + return {'data': self.get_object().import_flow(data)} diff --git a/passerelle/contrib/stub_invoices/views.py b/passerelle/contrib/stub_invoices/views.py index 2be4d80..27f513d 100644 --- a/passerelle/contrib/stub_invoices/views.py +++ b/passerelle/contrib/stub_invoices/views.py @@ -31,25 +31,25 @@ from .models import StubInvoicesConnector class InvoicesView(DetailView): model = StubInvoicesConnector - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): - return [x for x in self.get_object().get_invoices() if not x.get('payment_date')] + return {'data': [x for x in self.get_object().get_invoices() if not x.get('payment_date')]} class HistoryInvoicesView(DetailView): model = StubInvoicesConnector - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): - return [x for x in self.get_object().get_invoices() if x.get('payment_date')] + return {'data': [x for x in self.get_object().get_invoices() if x.get('payment_date')]} class InvoiceView(DetailView): model = StubInvoicesConnector - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): - return self.get_object().get_invoice(kwargs.get('invoice_id')) + return {'data': self.get_object().get_invoice(kwargs.get('invoice_id'))} class InvoicePDFView(DetailView): @@ -70,7 +70,7 @@ class InvoicePayView(DetailView): def dispatch(self, *args, **kwargs): return super(InvoicePayView, self).dispatch(*args, **kwargs) - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access') def post(self, request, *args, **kwargs): - return utils.response_for_json(request, {'data': None}) + return {'data': None} diff --git a/passerelle/contrib/teamnet_axel/views.py b/passerelle/contrib/teamnet_axel/views.py index 70daa30..bacd892 100644 --- a/passerelle/contrib/teamnet_axel/views.py +++ b/passerelle/contrib/teamnet_axel/views.py @@ -38,10 +38,10 @@ class DetailView(GenericDetailView): raise NotImplementedError @utils.protected_api('can_access') - @utils.to_json('api') + @utils.to_json() def get(self, request, *args, **kwargs): self.object = self.get_object() - return self.get_data(request, *args, **kwargs) + return {'data': self.get_data(request, *args, **kwargs)} class PingView(DetailView): @@ -159,11 +159,11 @@ class InvoicePayView(DetailView): def dispatch(self, *args, **kwargs): return super(InvoicePayView, self).dispatch(*args, **kwargs) - @utils.to_json('api') + @utils.to_json() @utils.protected_api('can_access') def post(self, request, *args, **kwargs): self.object = self.get_object() data = json.loads(request.body) - return self.object.pay_invoice(kwargs['regie_id'], + return {'data': self.object.pay_invoice(kwargs['regie_id'], kwargs['invoice_id'], data['transaction_id'], - data['transaction_date']) + data['transaction_date'])} diff --git a/passerelle/utils/jsonresponse.py b/passerelle/utils/jsonresponse.py index a86d557..3bc2b8f 100644 --- a/passerelle/utils/jsonresponse.py +++ b/passerelle/utils/jsonresponse.py @@ -6,7 +6,6 @@ import json import functools import logging import re -from collections import Iterable from django.http import HttpResponse, Http404, HttpResponseBadRequest from django.conf import settings @@ -30,18 +29,10 @@ class APIError(RuntimeError): class to_json(object): - def __init__(self, serializer_type, error_code=500, wrap_response=True, **kwargs): - """ - serializer_types: - * api - serialize buildin objects (dict, list, etc) in strict api - * objects - serialize list of region in strict api - * plain - just serialize result of function, do not wrap response and do not handle exceptions - """ - self.serializer_type = serializer_type + def __init__(self, error_code=500, **kwargs): self.method = None self.error_code = error_code self.kwargs = kwargs - self.wrap_response = wrap_response if 'cls' not in self.kwargs: self.kwargs['cls'] = DjangoJSONEncoder @@ -52,42 +43,21 @@ class to_json(object): return self.method(f, *args, **kwargs) if not args: - if self.serializer_type == 'plain': - self.method = self.plain_func - else: - self.method = self.api_func + self.method = self.api_func if getattr(getattr(args[0], f.__name__, None), "im_self", False): - if self.serializer_type == 'plain': - self.method = self.plain_method - else: - self.method = self.api_method + self.method = self.api_method else: - if self.serializer_type == 'plain': - self.method = self.plain_func - else: - self.method = self.api_func + self.method = self.api_func return self.method(f, *args, **kwargs) return wrapper def obj_to_response(self, req, obj): - if self.serializer_type == 'objects': - if isinstance(obj, Iterable): - obj = [o.serialize(req) if obj else None for o in obj] - elif obj: - obj = obj.serialize(req) - else: - obj = None - if self.wrap_response: - d = {"err": 0} - d.update({"data": obj}) - return d - else: - if isinstance(obj, dict) and not 'err' in obj: - obj['err'] = 0 - return obj + if isinstance(obj, dict) and not 'err' in obj: + obj['err'] = 0 + return obj def err_to_response(self, err): if hasattr(err, "__module__"): @@ -182,17 +152,3 @@ class to_json(object): status = self.error_code return self.render_data(req, data, status) - - def plain_method(self, f, *args, **kwargs): - data = f(*args, **kwargs) - if isinstance(data, HttpResponse): - return data - - return self.render_data(args[1], data) - - def plain_func(self, f, *args, **kwargs): - data = f(*args, **kwargs) - if isinstance(data, HttpResponse): - return data - - return self.render_data(args[0], data) diff --git a/passerelle/views.py b/passerelle/views.py index ba65d78..5b3b281 100644 --- a/passerelle/views.py +++ b/passerelle/views.py @@ -265,7 +265,6 @@ class GenericEndpointView(GenericConnectorMixin, SingleObjectMixin, View): return self.endpoint(request, **self.get_params(request, *args, **kwargs)) def get(self, request, *args, **kwargs): - json_decorator = to_json('api', wrap_response=False) if self.endpoint.endpoint_info.pattern: pattern = url(self.endpoint.endpoint_info.pattern, self.endpoint) match = pattern.resolve(kwargs.get('rest') or '') @@ -274,7 +273,7 @@ class GenericEndpointView(GenericConnectorMixin, SingleObjectMixin, View): kwargs['other_params'] = match.kwargs elif kwargs.get('rest'): raise Http404() - return json_decorator(self.perform)(request, *args, **kwargs) + return to_json()(self.perform)(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.get(request, *args, **kwargs) diff --git a/tests/test_jsonresponse.py b/tests/test_jsonresponse.py index 1a6a419..06fa91b 100644 --- a/tests/test_jsonresponse.py +++ b/tests/test_jsonresponse.py @@ -22,26 +22,26 @@ class LogAsWarningException(Exception): return 'log as warning exception' -@to_json('api') +@to_json() def wrapped_exception(req, *args, **kwargs): raise WrappedException -@to_json('api') +@to_json() def log_as_warning_exception(req, *args, **kwargs): raise LogAsWarningException -@to_json('api') +@to_json() def http404_exception(req, *args, **kwargs): raise Http404 -@to_json('api') +@to_json() def doesnotexist_exception(req, *args, **kwargs): raise ObjectDoesNotExist -@to_json('api') +@to_json() def permissiondenied_exception(req, *args, **kwargs): raise PermissionDenied @@ -104,19 +104,15 @@ def test_jsonresponse_log_as_warning_exception(caplog): def test_jsonresponse_error_header(): request = RequestFactory() req = request.get('/') - @to_json('api') + @to_json() def test_func(req): return {"test": "un test"} result = test_func(req) assert result.status_code == 200 data = json.loads(result.content) - assert 'err' in data - assert data['err'] == 0 - assert 'data' in data - assert 'test' in data['data'] - assert data['data']['test'] == 'un test' - @to_json('api') + assert data == {'test': 'un test', 'err': 0} + @to_json() def test_func(req): class CustomException(Exception): http_status = 200 @@ -135,20 +131,10 @@ def test_jsonresponse_with_http4O4_exception(): response = http404_exception(request.get('/')) assert response.status_code == 404 -def test_jsonresponse_without_wrapping(): - request = RequestFactory() - req = request.get('/') - @to_json('api', wrap_response=False) - def test_func(req): - return {"foo": "bar"} - result = test_func(req) - data = json.loads(result.content) - assert data == {"foo": "bar", "err": 0} - def test_jsonresponse_with_callback(): request = RequestFactory() req = request.get('/?callback=myfunc') - @to_json('api') + @to_json() def test_func(req): return {"foo": "bar"} result = test_func(req) @@ -156,13 +142,12 @@ def test_jsonresponse_with_callback(): assert 'application/javascript' in content_type assert result.content.startswith('myfunc(') args = json.loads(result.content[7:-2]) - assert args['err'] == 0 - assert args['data'] == {"foo": "bar"} + assert args == {'foo': 'bar', 'err': 0} def test_jsonresponse_with_wrong_callback(): request = RequestFactory() req = request.get('/?callback=myfunc()') - @to_json('api') + @to_json() def test_func(req): return {"foo": "bar"} result = test_func(req) -- 2.13.2