In this example, we are simulating a file with `io.BytesIO`, which is a file-like object that lives only in memory, but lets us use the same interface.
In this example, we are simulating a file with `io.BytesIO`, which is a file-like object that lives only in memory, but lets us use the same interface.
For example, we can iterate over it as we could with a file.
For example, we can iterate over it to consume its contents, as we could with a file.
@ -74,7 +74,7 @@ Only so that it can live in the same file for this example and you can copy it a
### Files and Async { #files-and-async }
### Files and Async { #files-and-async }
In most cases, file-like objects and interfaces are not compatible by default with async and await.
In most cases, file-like objects are not compatible with async and await by default.
For example, they don't have an `await file.read()`, or `async for chunk in file`.
For example, they don't have an `await file.read()`, or `async for chunk in file`.
@ -90,7 +90,7 @@ But in many cases reading a file or a file-like object would block.
To avoid blocking the event loop, you can simply declare the *path operation function* with regular `def` instead of `async def`, that way FastAPI will run it on a threadpool worker, to avoid blocking the main loop.
To avoid blocking the event loop, you can simply declare the *path operation function* with regular `def` instead of `async def`, that way FastAPI will run it on a threadpool worker, to avoid blocking the main loop.