Search code examples
pythonwebserverpython-asyncioaiohttp

Fetch file from localhost without web server


I want to fetch file from localhost without web server asynchronously. Seems that it is possible to do using file:// scheme. The following code sample is taken from documentation, but obviously it doesn't work:

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'file://localhost/Users/user/test.txt')
        print(html)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

How to make it work?

The one way I see is to use "curl file://path" in separate thread pool using run_in_executor, but I think there should be a way to fix code


Solution

  • If you need to obtain the contents of a local file, you can do it with ordinary Python built-ins, such as:

    with open('Users/user/test.txt') as rd:
        html = rd.read()
    

    If the file is not very large, and is stored on a local filesystem, you don't even need to make it async, as reading it will be fast enough not to disturb the event loop. If the file is large or reading it might be slow for other reasons, you should read it through run_in_executor to prevent it from blocking other asyncio code. For example (untested):

    def read_file_sync(file_name):
        with open('Users/user/test.txt') as rd:
            return rd.read()
    
    async def read_file(file_name):
        loop = asyncio.get_event_loop()
        html = await loop.run_in_executor(None, read_file_sync, file_name)
        return html