Created
May 26, 2022 04:19
-
-
Save rsyring/c099ca61b9e5eeb1537829f62b733e7f to your computer and use it in GitHub Desktop.
Write CSV files to a Zip file and serve with Falcon (Python)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
import io | |
import tempfile | |
import zipfile | |
import falcon | |
GB = 1024 ^ 3 | |
MEM_MAX_SIZE = 1 * GB | |
def add_csv(zf, fname, rows): | |
csv_fo = tempfile.SpooledTemporaryFile(max_size=MEM_MAX_SIZE, mode='w', encoding='utf-8') | |
cw = csv.writer(csv_fo) | |
for r in rows: | |
cw.writerow(r) | |
csv_fo.seek(0) | |
zf.writestr(fname, csv_fo.read()) | |
def create_zip(): | |
zip_fo = tempfile.SpooledTemporaryFile(max_size=MEM_MAX_SIZE, mode='w+b') | |
with zipfile.ZipFile(zip_fo, 'w', compression=zipfile.ZIP_DEFLATED) as zf: | |
add_csv(zf, 'letters.csv', ( | |
('a', 'b', 'c'), | |
('d', 'e', 'f'), | |
)) | |
add_csv(zf, 'numbers.csv', ( | |
('1', '2', '3'), | |
('4', '5', '6'), | |
)) | |
zip_fo.seek(0) | |
return zip_fo | |
class Index: | |
def on_get(self, req, resp): | |
resp.content_type = falcon.MEDIA_HTML # Default is JSON, so override | |
resp.text = 'Hello World!' | |
resp.text += '<a href="/csv">example csv</a>' | |
class CSV: | |
def on_get(self, req, resp): | |
resp.content_type = 'application/zip' | |
resp.set_header('Content-Disposition', 'attachment; filename=data.zip') | |
resp.stream = create_zip() | |
# falcon.App instances are callable WSGI apps | |
# in larger applications the app is created in a separate file | |
app = application = falcon.App() | |
app.add_route('/', Index()) | |
app.add_route('/csv', CSV()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can be ran with:
$ gunicorn --reload app