Skip to content

Commit 3b02bfe

Browse files
committed
made the implementation of ExportJSONMixin simpler by removing streaming of data and removed exclude_json_fields
Signed-off-by: Aayush Kumar <[email protected]>
1 parent d2b7497 commit 3b02bfe

File tree

4 files changed

+30
-71
lines changed

4 files changed

+30
-71
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ v34.10.2 (unreleased)
1313
if available, when the codebase has been sent for matching to MatchCode.
1414
https://github.com/aboutcode-org/scancode.io/pull/1656
1515

16+
- Add the ability to export filtered QuerySet of a FilterView into the JSON format.
17+
https://github.com/aboutcode-org/scancode.io/pull/1572
18+
1619
v34.10.1 (2025-03-26)
1720
---------------------
1821

scanpipe/pipes/output.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -280,16 +280,6 @@ def get_relations(self, project):
280280
)
281281

282282

283-
JSON_EXCLUDE_FIELDS = [
284-
"extra_data",
285-
"package_data",
286-
"license_detections",
287-
"other_license_detections",
288-
"license_clues",
289-
"affected_by_vulnerabilities",
290-
]
291-
292-
293283
def to_json(project):
294284
"""
295285
Generate output for the provided `project` in JSON format.

scanpipe/tests/test_views.py

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ def test_project_packages_export_json(self):
14041404
]
14051405

14061406
for field in expected_fields:
1407-
self.assertIn(field, json_data)
1407+
self.assertIn(field, json_data[0])
14081408

14091409
def test_project_dependencies_export_json(self):
14101410
make_resource_file(self.project1, "file.ext")
@@ -1437,7 +1437,7 @@ def test_project_dependencies_export_json(self):
14371437
]
14381438

14391439
for field in expected_fields:
1440-
self.assertIn(field, json_data)
1440+
self.assertIn(field, json_data[0])
14411441

14421442
def test_project_relations_export_json(self):
14431443
make_relation(
@@ -1465,7 +1465,7 @@ def test_project_relations_export_json(self):
14651465
]
14661466

14671467
for field in expected_fields:
1468-
self.assertIn(field, json_data)
1468+
self.assertIn(field, json_data[0])
14691469

14701470
def test_project_messages_export_json(self):
14711471
self.project1.add_message("warning")
@@ -1491,7 +1491,7 @@ def test_project_messages_export_json(self):
14911491
]
14921492

14931493
for field in expected_fields:
1494-
self.assertIn(field, json_data)
1494+
self.assertIn(field, json_data[0])
14951495

14961496
def test_project_codebase_resources_export_json(self):
14971497
make_resource_file(self.project1, "file.ext")
@@ -1515,13 +1515,25 @@ def test_project_codebase_resources_export_json(self):
15151515
"tag",
15161516
"extension",
15171517
"size",
1518+
"mime_type",
1519+
"file_type",
1520+
"programming_language",
1521+
"detected_license_expression",
1522+
"detected_license_expression_spdx",
1523+
"license_detections",
1524+
"license_clues",
1525+
"percentage_of_license_text",
1526+
"compliance_alert",
1527+
"copyrights",
1528+
"holders",
1529+
"authors",
1530+
"package_data",
1531+
"emails",
1532+
"urls",
15181533
"md5",
15191534
"sha1",
15201535
"sha256",
15211536
"sha512",
1522-
"mime_type",
1523-
"file_type",
1524-
"programming_language",
15251537
"is_binary",
15261538
"is_text",
15271539
"is_archive",
@@ -1531,37 +1543,8 @@ def test_project_codebase_resources_export_json(self):
15311543
"is_readme",
15321544
"is_top_level",
15331545
"is_key_file",
1534-
"detected_license_expression",
1535-
"detected_license_expression_spdx",
1536-
"percentage_of_license_text",
1537-
"compliance_alert",
1538-
"copyrights",
1539-
"holders",
1540-
"authors",
1541-
"emails",
1542-
"urls",
1543-
]
1544-
1545-
for field in expected_fields:
1546-
self.assertIn(field, json_data)
1547-
1548-
def test_scanpipe_views_export_json_excludes_fields(self):
1549-
make_resource_file(self.project1, "file.ext")
1550-
1551-
url = reverse("project_resources", args=[self.project1.slug])
1552-
response = self.client.get(url + "?export_json=True")
1553-
1554-
file_content = b"".join(response.streaming_content).decode("utf-8")
1555-
json_data = json.loads(file_content)
1556-
1557-
excluded_fields = [
15581546
"extra_data",
1559-
"package_data",
1560-
"license_detections",
1561-
"other_license_detections",
1562-
"license_clues",
1563-
"affected_by_vulnerabilities",
15641547
]
15651548

1566-
for field in excluded_fields:
1567-
self.assertNotIn(field, json_data)
1549+
for field in expected_fields:
1550+
self.assertIn(field, json_data[0])

scanpipe/views.py

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from django.core.exceptions import SuspiciousFileOperation
3737
from django.core.exceptions import ValidationError
3838
from django.core.files.storage.filesystem import FileSystemStorage
39+
from django.core.serializers.json import DjangoJSONEncoder
3940
from django.db.models import Prefetch
4041
from django.db.models.manager import Manager
4142
from django.http import FileResponse
@@ -513,25 +514,15 @@ def get_export_json_queryset(self):
513514
def get_export_json_filename(self):
514515
return f"{self.project.name}_{self.model._meta.model_name}.json"
515516

516-
def get_filtered_files(self, queryset):
517+
def export_json_file_response(self):
517518
from scanpipe.api.serializers import get_model_serializer
518519

519-
serializer_class = get_model_serializer(queryset.model)
520-
521-
yield from self.encode_queryset(queryset, serializer_class)
522-
523-
def export_json_file_response(self):
524520
queryset = self.get_export_json_queryset()
521+
serializer_class = get_model_serializer(queryset.model)
522+
serializer = serializer_class(queryset, many=True)
523+
serialized_data = json.dumps(serializer.data, indent=2, cls=DjangoJSONEncoder)
525524

526-
output_file = io.BytesIO()
527-
528-
first = True
529-
for chunk in self.get_filtered_files(queryset):
530-
if not first:
531-
output_file.write(b",\n")
532-
output_file.write(chunk.encode("utf-8"))
533-
first = False
534-
output_file.seek(0)
525+
output_file = io.BytesIO(serialized_data.encode("utf-8"))
535526

536527
return FileResponse(
537528
output_file,
@@ -540,14 +531,6 @@ def export_json_file_response(self):
540531
content_type="application/json",
541532
)
542533

543-
def encode_queryset(self, queryset, serializer_class):
544-
for obj in queryset.iterator(chunk_size=2000):
545-
data = serializer_class(obj).data
546-
for field in output.JSON_EXCLUDE_FIELDS:
547-
data.pop(field, None)
548-
549-
yield json.dumps(data, indent=2)
550-
551534
def get_context_data(self, **kwargs):
552535
context = super().get_context_data(**kwargs)
553536

0 commit comments

Comments
 (0)