Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement parkings data export capability #227

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

HotStew
Copy link

@HotStew HotStew commented Feb 4, 2022

Export button to toggle options rendering

image


Nothing selected, start & end time automatically set.

image


Filters selected

image


CSV file

image


Task requirements:

Export parkings data to CSV file.

  • Fields included in CSV must be: Location coordinates, terminal number, start time, end time, created at -time, modified at -time, operator, payment zone.
  • User may filter data to be exported with: operator(multi select), payment zone(multi slect), time range (start & end), parking checked.
  • For now, filter by activity in time range. So if parking was active anytime within the time range.

Comments

One main complaint is the UX when downloading. In a case where the user filtered for >100k parking objects, it will take a long time for the server to respond, because iterating over so many objects takes a long time. So after clicking the download button, users can expect a waiting time of 10's of seconds of nothing happening (and hope the user doesn't click the download button multiple times because they are confused why nothing his happening). Also to mention that the RAM usage of the server may also suffer since there are so many parking objects.

@HotStew HotStew changed the title Implement parkings data export capability WIP: Implement parkings data export capability Feb 4, 2022
@HotStew HotStew changed the title WIP: Implement parkings data export capability Implement parkings data export capability Feb 7, 2022
@HotStew HotStew force-pushed the export-parkings-data branch 2 times, most recently from 910b4ee to 125959e Compare May 2, 2022 07:51
@suutari-ai suutari-ai closed this May 17, 2022
@suutari-ai
Copy link
Collaborator

Oops, closed this by accident while closing some some cruft PRs in bulk.

@suutari-ai suutari-ai reopened this May 17, 2022
@suutari-ai
Copy link
Collaborator

You shouldn't use f-strings, since they are not supported with Python 3.5.

Please fix the style issues too.

@HotStew HotStew force-pushed the export-parkings-data branch 2 times, most recently from f27050d to c3f7a0f Compare May 24, 2022 14:18
Comment on lines +14 to +16
class CSVRenderer(renderers.BaseRenderer):
media_type = "text/csv"
format = "csv"
render_style = 'binary'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should use a ready-made DRF CSV renderer rather than implementing your own.

There's at least https://github.com/mjumbewu/django-rest-framework-csv which should do the job.

Kevin Seestrand added 8 commits May 24, 2022 17:39
New endpoints:

- /monitoring/v1/export/download/
Responds with a string that contains all the csv lines.
Start time and end time are required fields.
Create a custom CSVRenderer for this endpoints.
When it comes to filtering data with the time we do it by having
a time range where any parking that was active during
the range gets exported. This means that any parking
that started before range and ended before range OR started
after range will not get filtered in.
One important thing to mention is that if the queryset
ends up being very big (>100k objs) ram usage may suffer
and the user will have to wait a long time for a response from
the server since we don't stream the response.
In a case of an action that uses the CSVRenderer
raises an exception, change the renderer to a
JSONRenderer so the server can respond with an
error message with correct data format.

We have to bypass the custom CSVRenderer because
otherwise the validation error message gets passed
over to the CSVRenderer and the CSVRenderer can't
really do anything with the error message.
Expose custom header 'x-suggested-filename' so that
the dashboard can use it for naming the csv file.
Also create a utility download function that downloads
the CSV file as a blob.
Operators and PaymentZones get stored in root state.
Create Export component.

Create new 'onMount' dispatch. This calls the 'fetchData' function.
The data in question which is Operators and Payment zones only need to
get fetched once.
@HotStew HotStew force-pushed the export-parkings-data branch from c3f7a0f to e1d76f7 Compare May 24, 2022 14:39
Comment on lines +24 to +49
kwargs = {
"time_start__lte": time_end,
"time_end__gte": time_start,
}

if payment_zones:
kwargs["zone__code__in"] = payment_zones
if operators:
kwargs["operator__id__in"] = operators

parkings = (
Parking.objects
.filter(**kwargs)
.order_by("-time_start")
.prefetch_related("operator", "zone")
)

if parking_check:
parking_check_parking_ids = (
ParkingCheck.objects
.filter(found_parking__id__in=parkings)
.order_by("found_parking")
.values_list("found_parking")
.distinct()
)
parkings = parkings.filter(id__in=parking_check_parking_ids)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filtering code here doesn't seem to belong to the CSV renderer, but rather to the ViewSet, or even better they should be implemented as FilterSets. See e.g. parkings/api/enforcement/valid_parking.py for an example of FilterSet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants