I am using FastAPI to upload a csv file, perform some modifications on it and then return it to the HTML page. I am using Jinja2 as the template engine and HTML in frontend.
How can I upload the csv file using Jinja2 template, modify it and then return it to the client?
Python code
from fastapi.templating import Jinja2Templates
from fastapi import FastAPI, File, UploadFile, Request
from io import BytesIO
import pandas as pd
import uvicorn
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/")
def form_post(request: Request):
result = "upload file"
return templates.TemplateResponse('home.html', context={'request': request, 'result': result})
@app.post("/")
def upload(request: Request, file: UploadFile = File(...)):
contents1 = file.file.read()
buffer1 = BytesIO(contents1)
test1 = pd.read_csv(buffer1)
buffer1.close()
file.file.close()
test1 = dict(test1.values)
return templates.TemplateResponse('home.html', context={'request': request, 'result': test1})
if __name__ == "__main__":
uvicorn.run(app)
HTML code
\<!DOCTYPE html\>
\<html lang="en"\>
\<head\>
\<meta charset="UTF-8"\>
\<title\>RUL_PREDICTION\</title\>
\</head\>
\<body\>
\<h1\>RUL PREDICTION\</h1\>
\<form method="post"\>
\<input type="file" name="file" id="file"/\>
\<button type="submit"\>upload\</button\>
\</form\>
\<p\>{{ result }}\</p\>
\</body\>
\</html\>
CodePudding user response:
This might work:
@app.post("/")
def upload(file: UploadFile):
with open("temp.csv", "wb") as f:
for row in file.file:
f.write(row)
with open("temp.csv", "r", encoding="utf-8") as csv:
# modifications
return FileResponse(path="temp.csv", filename="new.csv", media_type="application/octet-stream")
CodePudding user response:
The working example below is derived from the answers here, here, as well as here, here and here, at which I would suggest you have a look for more details and explanation.
Sample data
data.csv
Id,name,age,height,weight
1,Alice,20,62,120.6
2,Freddie,21,74,190.6
3,Bob,17,68,120.0
Backend
app.py
from fastapi import FastAPI, File, UploadFile, Request, Response, HTTPException
from fastapi.templating import Jinja2Templates
from io import BytesIO
import pandas as pd
app = FastAPI()
templates = Jinja2Templates(directory='templates')
@app.post('/upload')
def upload(file: UploadFile = File(...)):
try:
contents = file.file.read()
buffer = BytesIO(contents)
df = pd.read_csv(buffer)
except:
raise HTTPException(status_code=500, detail='Something went wrong')
finally:
buffer.close()
file.file.close()
# remove a column from the DataFrame
df.drop('age', axis=1, inplace=True)
headers = {'Content-Disposition': 'attachment; filename="modified_data.csv"'}
return Response(df.to_csv(), headers=headers, media_type='text/csv')
@app.get('/')
def main(request: Request):
return templates.TemplateResponse('index.html', {'request': request})
Frontend
templates/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data">
<label for="csvFile">Choose a CSV file</label>
<input type="file" id="csvFile" name="file" onchange="enableSubmitBtn();"><br><br>
<input type="submit" id="submitBtn" value="submit" disabled>
</form>
<script>
function enableSubmitBtn() {
document.getElementById('submitBtn').removeAttribute("disabled");
}
</script>
</body>
</html>