Skip to content

Commit

Permalink
Improve remaining APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
hipek8 committed Sep 27, 2024
1 parent f2dd1d3 commit 71819a1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
30 changes: 20 additions & 10 deletions src/ralph/api/tests/test_rendering.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
from importlib import import_module

from ddt import data, ddt
Expand All @@ -19,6 +20,8 @@ class APIBrowsableClient(APIClient):
default_format = 'text/html'


# If you want to test all items in the API, set BROWSE_ALL_API_ITEMS=1 env
BROWSE_ALL_API_ITEMS = os.environ.get('BROWSE_ALL_API_ITEMS', False)
DEFAULT_MAX_QUERIES = 20
# To get this just visit /api in your browser
ALL_API_ENDPOINTS = {
Expand All @@ -29,7 +32,9 @@ class APIBrowsableClient(APIClient):
"assetmodels": "/api/assetmodels/",
"back-office-assets": "/api/back-office-assets/",
"base-object-clusters": "/api/base-object-clusters/",
"base-objects": ("/api/base-objects/", 50),
# BaseObjectViewSet is a polymorphic viewset and in worst case it can generate many SQL queries
# (some number per each different model) but not really N+1 for larger Ns.
"base-objects": ("/api/base-objects/", 60),
"base-objects-licences": "/api/base-objects-licences/",
"base-objects-supports": "/api/base-objects-supports/",
"budget-info": "/api/budget-info/",
Expand Down Expand Up @@ -150,12 +155,17 @@ def test_json_endpoint(self, model_name):
if isinstance(ALL_API_ENDPOINTS[model_name], tuple) \
else (ALL_API_ENDPOINTS[model_name], DEFAULT_MAX_QUERIES)
self.client.force_authenticate(self.user)
with CaptureQueriesContext(connections['default']) as cqc:
response = self.client.get(endpoint, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertGreater(len(response.json()['results']), 0)
self.assertLessEqual(len(cqc.captured_queries), max_queries,
msg=f"Too many queries when getting {endpoint}."
f"\nQueries count: {len(cqc.captured_queries)}."
"\nQueries:\n" + "\n".join(query['sql'] for query in cqc.captured_queries)
)
while True:
with CaptureQueriesContext(connections['default']) as cqc:
response = self.client.get(endpoint, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertGreater(len(response.json()['results']), 0)
self.assertLessEqual(
len(cqc.captured_queries), max_queries,
msg=f"Too many queries when getting {endpoint}."
f"\nQueries count: {len(cqc.captured_queries)}."
"\nQueries:\n" + "\n".join(query['sql'] for query in cqc.captured_queries)
)
endpoint = response.json()['next']
if not BROWSE_ALL_API_ITEMS or endpoint is None:
break
16 changes: 11 additions & 5 deletions src/ralph/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,20 @@ class PolymorphicListSerializer(serializers.ListSerializer):
"""
def __init__(self, *args, **kwargs):
self.child_serializers = kwargs.pop('child_serializers')
return super().__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def to_representation(self, data):
iterable = data.all() if isinstance(data, models.Manager) else data
return [
self.child_serializers[item.__class__].to_representation(item)
for item in iterable if self.child_serializers.get(item.__class__)
]
def iterate():
for item in iterable:
if self.child_serializers.get(item.__class__):
yield self.child_serializers[item.__class__].to_representation(item)
else:
try:
yield {"id": item.id}
except Exception:
yield {}
return [i for i in iterate()]


class PolymorphicSerializer(serializers.Serializer):
Expand Down
5 changes: 3 additions & 2 deletions src/ralph/licences/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ class LicenceUserViewSet(RalphAPIViewSet):
queryset = LicenceUser.objects.all()
serializer_class = LicenceUserSerializer
select_related = [
'licence', 'licence__region', 'licence__manufacturer',
'licence__licence_type', 'licence__software', 'user'
'licence__region', 'licence__manufacturer', 'licence__office_infrastructure',
'licence__licence_type', 'licence__software', 'licence__budget_info',
'user'
]


Expand Down

0 comments on commit 71819a1

Please sign in to comment.