Gunicorn flask app can't download file using playwright on linux

Question:

I’m making a ReST API using Flask and Playwright to download some files on a server. Locally, it works but, in server (Linux), returns a permission error.

file = await self._loop.run_in_executor(None, lambda: open(path, "wb"))
PermissionError: [Errno 13] Permission denied: '/var/apis/tceprotocolo/infos-(19).html'
local_save = '/var/apis/tceprotocolo'
def atualiza_json_consultas():
    campos = ['Situação', 'Número', 'Órgão', 'Convenente', 'CPF/CNPJ Convenente', 'Objeto', 'Ínicio', 'Fim', 'Valor Concedente', 'Val']  
    anoa = int(datetime.datetime.now().date().strftime("%Y")) - 4
    try:
        with sync_playwright() as p:
            nav = p.chromium.launch()
            for ano in range(anoa, anoa+5):
                page = nav.new_page()
                temp_ano = []
                page.goto(link)
    with page.expect_download() as download_i:
                    try:
                        page.locator('//html//body//div[1]//div[4]//button').click()
                    except:
                        page.close()
                        page.goto(link)
                        page.locator('//html//body//div[1]//div[4]//button').click()
                    page.locator('//html//body//div[1]//div[4]//ul//li[2]//a').click()
                dl = download_i.value   
                workin_dirf = f'{local_save}/infos-({str(ano)[2:]}).html'
                dl.save_as(workin_dirf)
                page.close()

Error occurs on dl.save_as(workin_dirf).

I’ve tried to execute gunicorn3 with sudo but it doesn’t find some modules and, when I fixed it, the script started to works on different folder.

Asked By: J.N.N

||

Answers:

It would appear that when you run the script on your server, the user you’re using does not have permission to create either the local_save directory or the path to that directory. On a Unix-like system, /var and most of its subdirectories are generally writable only by root. The exception is /var/tmp. If you change your local_save variable to be

local_save = '/var/tmp/apis/tceprotocolo'

and prior to calling your function, call

os.makedirs(local_save)

then your function should successfully write output to that directory.

Answered By: James McPherson

As an alternative to the accepted answer, I suggest you learn about the tempfile module in python. This gives you some functionality to create temp files. One of the main benefits is that you don’t have to hardcode the path to the temp directory.

Answered By: Code-Apprentice