Code Monkey home page Code Monkey logo

Comments (12)

inverse-panda avatar inverse-panda commented on May 13, 2024 1

Is there any update on this issue? I have the same problem , just migrated from v0.103.0 to v0.108.0 and realized my tests are failing due the same issue. Is is related to this breaking change?
If yes, what is the proposed approach for handling the UploadFile in the background task?
my old practice is written below

async def upload_csv_to_gcloud_blob_storage(
    self, file: UploadFile, bucket_name: str, blob_storage_path:str
):
    """write the data to a bucket with"""
    storage_client = storage.Client()
    csv_bucket = storage_client.bucket(bucket_name)
    blob = csv_bucket.blob(blob_storage_path)

    try:
        with blob.open("wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
    finally:
        file.file.close()
            
@app.post( "/csv_tables" )
async def upload_csv(
    csv_file: Annotated[UploadFile, File()],
    background_tasks: BackgroundTasks,
):
  
    background_tasks.add_task(
        upload_csv_to_gcloud_blob_storage,
        csv_file=csv_file,
        bucket_name="csv",
        blob_storage_path="csv_path",
    )
    return "OK"

from fastapi.

daviddavis avatar daviddavis commented on May 13, 2024

We ran into this issue. Calling file.read() in code our began raising an error after upgrading fastapi: ValueError: I/O operation on closed file.

from fastapi.

adlmtl avatar adlmtl commented on May 13, 2024

I'm having similar issue with a tempfile I'm yielding....

def create_temp_file():
    fd, path = tempfile.mkstemp(suffix='.csv')
    try:
        yield fd, path
    finally:
        os.unlink(path)

When I try to return the file in a FileResponse I hit:
RuntimeError(f"File at path {self.path} does not exist.")

from fastapi.

msehnout avatar msehnout commented on May 13, 2024

Is there any update on this issue? I have the same problem , just migrated from v0.103.0 to v0.108.0 and realized my tests are failing due the same issue. Is is related to this breaking change? If yes, what is the proposed approach for handling the UploadFile in the background task? my old practice is written below

It seems to be, removing this line prevent the file in the body from being closed:

async_exit_stack.push_async_callback(body.close)

It was introduced in the only commit changing the code between versions 105 and 106:
a4aa79e#diff-4d573079004a9f3d148baa4658e68e82b8a3d1a95d603fee8177daa92cf65c93R231

Unfortunately the get_request_handler is not trivial, so I cannot create PR without a bit of help.

from fastapi.

msehnout avatar msehnout commented on May 13, 2024

I went through the get_request_handler function again and maybe the behavior is intentional? I don't know. Anyway the problem is that it simply runs the endpoint handler:

raw_response = await run_endpoint_function(

and then closes the file. But in case the handler is asynchronous, like a background task:

@app.post(...)
async def foo():
   background_tasks.add_task(process_recording_file, file=file, ...)

it closes the file before the task can actually run. So I created a deep copy like this:

-background_tasks.add_task(process_recording_file, file=file, ...)
+background_tasks.add_task(process_recording_file, file=copy.deepcopy(file), ...)

and I close the file myself in the function:

async def process_recording_file(file: UploadFile...):
    try:
        ...
    finally:
        await file.close()

which fixes the issue even with the newest version of FastAPI. It is probably not very efficient given that the file is few MB in my case.

So maybe a better question would be, what is the expected usage of UploadFile combined with BackgroundTasks? https://fastapi.tiangolo.com/tutorial/background-tasks/

from fastapi.

wu-clan avatar wu-clan commented on May 13, 2024

Hi, @msehnout

Interesting thinking, but I don't think it's a backstage task. Look at this.:encode/starlette#2176 (comment)

from fastapi.

Kludex avatar Kludex commented on May 13, 2024

How is my comment related?

from fastapi.

wu-clan avatar wu-clan commented on May 13, 2024

I just want to express that the idea of @ msehnout may be backward incompatible because he mentioned background tasks,it seems to have nothing to do with your comments?

from fastapi.

rushilsrivastava avatar rushilsrivastava commented on May 13, 2024

I'm having similar issue with a tempfile I'm yielding....

def create_temp_file():
    fd, path = tempfile.mkstemp(suffix='.csv')
    try:
        yield fd, path
    finally:
        os.unlink(path)

When I try to return the file in a FileResponse I hit: RuntimeError(f"File at path {self.path} does not exist.")

Related discussion: #10850

I am assuming create_temp_file is used as a dependency. This error is happening because the dependency is fully resolved before the response is returned to the client. Previously, this worked because the exit code was executed after the response was sent. At the moment, I think the only way to work around this is using Background Tasks, as discussed in #2512.

from fastapi.

msehnout avatar msehnout commented on May 13, 2024

I'm not sure the problem I'm experiencing is actually an issue or a bad design choice on my side, so I created a discussion instead: #10936

from fastapi.

tjbck avatar tjbck commented on May 13, 2024

Any updates on this? deepcopying isn't an option for me.

from fastapi.

uniartisan avatar uniartisan commented on May 13, 2024

Looking forward to an update. copy.deepcopy not work for me. I have no choice but to downgrade fastapi

from fastapi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.