0

I'm using FastAPI to write an API to upload text files and to read the txt file contents.

@app.post('/read_txt_file', response_class=PlainTextResponse)
async def upload_file_and_read(file: UploadFile = File(...)
                      , fileExtension: str = Form(...)):
 
    if(fileExtension == 'txt'):
        raw_txt = readTxt(file)
        raw_txt = raw_txt.decode()

    return raw_txt


def readTxt(file):
    return file.read()

This code above throws internal server error. Can I know how to correct it?

Logs:

File "/home/readerProject/.venv/lib/python3.7/site-packages/fastapi/routing.py", line 183, in app dependant=dependant, values=values, is_coroutine=is_coroutine File "/home/readerProject/.venv/lib/python3.7/site-packages/fastapi/routing.py", line 133, in run_endpoint_function return await dependant.call(**values)

File "/home/readerProject/api.py", line 28, in upload_file_and_read raw_txt = raw_txt.decode()

AttributeError: 'coroutine' object has no attribute 'decode' /home/readerProject/.venv/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py:396: RuntimeWarning: coroutine 'UploadFile.read' was never awaited
self.transport.close() RuntimeWarning: Enable tracemalloc to get the object allocation traceback

3
  • 2
    raw_txt = await raw_txt.decode() instead of raw_txt = raw_txt.decode() ? Commented Oct 15, 2020 at 7:58
  • why do we need await ? most importantly when do we have to use await ? Commented Oct 15, 2020 at 8:00
  • You are using a coroutine so you definitely need to use await like @ArakkalAbu mentioned, since it is not a function and you can't directly return it, See PEP 492 Commented Oct 15, 2020 at 8:04

1 Answer 1

3

You have to call the readTxt(...) function with await syntax as

raw_txt = await readTxt(file)
         ^^^^^^^

Minimal verifiable example

from fastapi import FastAPI, UploadFile, File

app = FastAPI()


@app.post('/read_txt_file')
async def upload_file_and_read(
        file: UploadFile = File(...),
):
    if file.content_type.startswith("text"):
        text_binary = await readTxt(file) # call `await`
        response = text_binary.decode()
    else:
        # do something
        response = file.filename

    return response


def readTxt(file):
    return file.read()

As a side note, you can retrieve the context type by inspecting the file.content_type which can be used to identify the file extension.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.