Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

[Issue #86] Download the search response as a CSV file #87

Merged
merged 23 commits into from
Jul 29, 2024

Conversation

chouinar
Copy link
Collaborator

Summary

Fixes #86

Time to review: 10 mins

Changes proposed

Modified the search endpoint to be able to return its response as a CSV file

Context for reviewers

My understanding is that the CSV download in the current experience is a frequently used feature - so adding it is worthwhile.

An important detail is that all it takes to switch from getting the response as a normal JSON response body is to change the new "format" field in the request. So if the frontend added a new download button, they would just make an identical request adding this format field (they'd likely want to also adjust the page size to return more than 25 items).

The actual logic is pretty simple, instead of return the normal JSON body, we instead construct a CSV file object and return that. There is some level of formatting/parsing that we need to do with this, but its pretty minor. Note that it is explicit with which fields it returns that way the CSV won't keep changing on users if we make adjustments to the schemas elsewhere.

As for returning the file, it just relies on Flask itself. I'm not as familiar with file operations in an endpoint like this, so if there are scaling concerns (ie. very large output files), let me know. I know there are a few tools in Flask for streaming file responses and other complexities.

If we wanted to add support for more file types like a JSON file or XML, we'd just need to add converters for those and the file logic should all work the same. I originally implemented this as JSON but realized it was just the exact response body shoved in a file - if a user wants that they might just create the file themselves from the API response.

Additional information

You can see what the file looks like that this produced either by running the API yourself, or looking at this one I generated.

Note that for the list fields, I used ; to separate the values within a single cell.

opportunity_search_results_20240617-152953.csv

acouch
acouch previously approved these changes Jun 26, 2024
Base automatically changed from chouinar/16-actual-impl to main June 27, 2024 20:07
@chouinar chouinar dismissed acouch’s stale review June 27, 2024 20:07

The base branch was changed.

@chouinar chouinar merged commit 9150efd into main Jul 29, 2024
8 checks passed
@chouinar chouinar deleted the chouinar/86-csv-download branch July 29, 2024 14:09
acouch pushed a commit that referenced this pull request Sep 18, 2024
Fixes HHS#2064

Modified the search endpoint to be able to return its response as a CSV
file

My understanding is that the CSV download in the current experience is a
frequently used feature - so adding it is worthwhile.

An important detail is that all it takes to switch from getting the
response as a normal JSON response body is to change the new "format"
field in the request. So if the frontend added a new download button,
they would just make an identical request adding this format field
(they'd likely want to also adjust the page size to return more than 25
items).

The actual logic is pretty simple, instead of return the normal JSON
body, we instead construct a CSV file object and return that. There is
some level of formatting/parsing that we need to do with this, but its
pretty minor. Note that it is explicit with which fields it returns that
way the CSV won't keep changing on users if we make adjustments to the
schemas elsewhere.

As for returning the file, it just relies on Flask itself. I'm not as
familiar with file operations in an endpoint like this, so if there are
scaling concerns (ie. very large output files), let me know. I know
there are a few tools in Flask for streaming file responses and other
complexities.

If we wanted to add support for more file types like a JSON file or XML,
we'd just need to add converters for those and the file logic should all
work the same. I originally implemented this as JSON but realized it was
just the exact response body shoved in a file - if a user wants that
they might just create the file themselves from the API response.

You can see what the file looks like that this produced either by
running the API yourself, or looking at this one I generated.

Note that for the list fields, I used `;` to separate the values within
a single cell.

[opportunity_search_results_20240617-152953.csv](https://github.com/user-attachments/files/15873437/opportunity_search_results_20240617-152953.csv)

---------

Co-authored-by: nava-platform-bot <[email protected]>
acouch pushed a commit that referenced this pull request Sep 18, 2024
Fixes HHS#2064

Modified the search endpoint to be able to return its response as a CSV
file

My understanding is that the CSV download in the current experience is a
frequently used feature - so adding it is worthwhile.

An important detail is that all it takes to switch from getting the
response as a normal JSON response body is to change the new "format"
field in the request. So if the frontend added a new download button,
they would just make an identical request adding this format field
(they'd likely want to also adjust the page size to return more than 25
items).

The actual logic is pretty simple, instead of return the normal JSON
body, we instead construct a CSV file object and return that. There is
some level of formatting/parsing that we need to do with this, but its
pretty minor. Note that it is explicit with which fields it returns that
way the CSV won't keep changing on users if we make adjustments to the
schemas elsewhere.

As for returning the file, it just relies on Flask itself. I'm not as
familiar with file operations in an endpoint like this, so if there are
scaling concerns (ie. very large output files), let me know. I know
there are a few tools in Flask for streaming file responses and other
complexities.

If we wanted to add support for more file types like a JSON file or XML,
we'd just need to add converters for those and the file logic should all
work the same. I originally implemented this as JSON but realized it was
just the exact response body shoved in a file - if a user wants that
they might just create the file themselves from the API response.

You can see what the file looks like that this produced either by
running the API yourself, or looking at this one I generated.

Note that for the list fields, I used `;` to separate the values within
a single cell.

[opportunity_search_results_20240617-152953.csv](https://github.com/user-attachments/files/15873437/opportunity_search_results_20240617-152953.csv)

---------

Co-authored-by: nava-platform-bot <[email protected]>
acouch pushed a commit to HHS/simpler-grants-gov that referenced this pull request Sep 18, 2024
Fixes #2064

Modified the search endpoint to be able to return its response as a CSV
file

My understanding is that the CSV download in the current experience is a
frequently used feature - so adding it is worthwhile.

An important detail is that all it takes to switch from getting the
response as a normal JSON response body is to change the new "format"
field in the request. So if the frontend added a new download button,
they would just make an identical request adding this format field
(they'd likely want to also adjust the page size to return more than 25
items).

The actual logic is pretty simple, instead of return the normal JSON
body, we instead construct a CSV file object and return that. There is
some level of formatting/parsing that we need to do with this, but its
pretty minor. Note that it is explicit with which fields it returns that
way the CSV won't keep changing on users if we make adjustments to the
schemas elsewhere.

As for returning the file, it just relies on Flask itself. I'm not as
familiar with file operations in an endpoint like this, so if there are
scaling concerns (ie. very large output files), let me know. I know
there are a few tools in Flask for streaming file responses and other
complexities.

If we wanted to add support for more file types like a JSON file or XML,
we'd just need to add converters for those and the file logic should all
work the same. I originally implemented this as JSON but realized it was
just the exact response body shoved in a file - if a user wants that
they might just create the file themselves from the API response.

You can see what the file looks like that this produced either by
running the API yourself, or looking at this one I generated.

Note that for the list fields, I used `;` to separate the values within
a single cell.

[opportunity_search_results_20240617-152953.csv](https://github.com/user-attachments/files/15873437/opportunity_search_results_20240617-152953.csv)

---------

Co-authored-by: nava-platform-bot <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Task]: Add the ability to download the search response as a CSV file
3 participants