flet-dev / flet

Flet enables developers to easily build realtime web, mobile and desktop apps in Python. No frontend experience required.
https://flet.dev
Apache License 2.0
9.95k stars 392 forks source link

FilePickerUploadFile can not upload file to webserver #2381

Open AngRotanak opened 5 months ago

AngRotanak commented 5 months ago

I hosint my app with Cloud run FilePickerUploadFile can not upload file to webserver

Get Error:

2024-01-12 13:52:58.080 ICT Exception: Specify secret_key parameter or set FLET_SECRET_KEY environment variable to enable uploads. Open in Logs Explorer { insertId: "65a0e1ca00013a5be2a672be" labels: {1} logName: "projects/khmer-autotools/logs/run.googleapis.com%2Fstderr" receiveTimestamp: "2024-01-12T06:52:58.329130140Z" resource: {2} textPayload: "Exception: Specify secret_key parameter or set FLET_SECRET_KEY environment variable to enable uploads." timestamp: "2024-01-12T06:52:58.080475Z" }

as my code:

`import json import os import shutil

import flet_fastapi from typing import Dict

import flet from flet import ( Column, ElevatedButton, FilePicker, FilePickerResultEvent, FilePickerUploadEvent, FilePickerUploadFile, Page, ProgressRing, Ref, Row, Text, icons, )

mnt_dir = os.environ.get("MNT_DIR", "/mnt/nfs/filestore") async def main(page: Page): prog_bars: Dict[str, ProgressRing] = {} files = Ref[Column]() upload_button = Ref[ElevatedButton]()

config_data = {
    "max_add_count": 'max_add_count',
    "add_index": 'add_index',
    "adding_status": 'adding_status',
    "scrape_group": 'scrape_group',
    "add_group": 'add_group'
}

with open(f"{mnt_dir}/config.json", "w") as jsonfile:
    json.dump(config_data, jsonfile, indent=4)
    jsonfile.close()

async def file_picker_result(e: FilePickerResultEvent):
    upload_button.current.disabled = True if e.files is None else False
    prog_bars.clear()
    files.current.controls.clear()
    if e.files is not None:
        for f in e.files:
            prog = ProgressRing(value=0, bgcolor="#eeeeee", width=20, height=20)
            prog_bars[f.name] = prog
            files.current.controls.append(Row([prog, Text(f.name)]))
    await page.update_async()

async def on_upload_progress(e: FilePickerUploadEvent):
    prog_bars[e.file_name].value = e.progress
    await prog_bars[e.file_name].update_async()

file_picker = FilePicker(on_result=file_picker_result, on_upload=on_upload_progress)

async def pick_files(e):
    await file_picker.pick_files_async(allow_multiple=True)

async def upload_files(e):
    uf = []
    if file_picker.result is not None and file_picker.result.files is not None:
        for f in file_picker.result.files:
            uf.append(
                FilePickerUploadFile(
                    f.name,
                    upload_url=await page.get_upload_url_async(f.name, 600),
                )
            )
        await file_picker.upload_async(uf)

# hide dialog in a overlay
page.overlay.append(file_picker)

await page.add_async(
    ElevatedButton(
        "Select files...",
        icon=icons.FOLDER_OPEN,
        on_click=pick_files,
    ),
    Column(ref=files),
    ElevatedButton(
        "Upload",
        ref=upload_button,
        icon=icons.UPLOAD,
        on_click=upload_files,
        disabled=True,
    ),
)

app = flet_fastapi.app(main, upload_dir=f"uploads")

flet.app(target=main, upload_dir="uploads", view=flet.WEB_BROWSER)`

hidara2000 commented 3 months ago

I started playing with Flet yesterday and had a similar issue. The code below is rough but uploads are working. For some reason, the last increment in the progress bar is very slow for large files. I'm also guessing you could permanently add 'FLET_SECRET_KEY' env permanently to ~./bashrc or ~./zshrc

import os
import flet as ft

def main(page: ft.Page):
    prog_bar = ft.ProgressBar(value=0, bgcolor="#eeeeee", width=400)
    prog_bar.visible = False

    def on_dialog_result(e: ft.FilePickerResultEvent):
        print("Selected files:", e.files)
        upload_files()

    def upload_files():
        upload_list = []
        if file_picker.result != None and file_picker.result.files != None:
            for f in file_picker.result.files:
                upload_list.append(
                    ft.FilePickerUploadFile(
                        f.name,
                        upload_url=page.get_upload_url(f.name, 600),
                    )
                )
            prog_bar.visible = True
            page.update()
            file_picker.upload(upload_list)

    def on_upload_progress(e: ft.FilePickerUploadEvent):
        prog_bar.value = e.progress
        print(prog_bar.value)

        if int(e.progress) == 1:
            prog_bar.visible = False
        prog_bar.update()

    file_picker = ft.FilePicker(
        on_result=on_dialog_result, on_upload=on_upload_progress
    )

    file_picker_btn = ft.ElevatedButton(
        "Choose files...",
        on_click=lambda _: file_picker.pick_files(
            allow_multiple=False,
            allowed_extensions=["mp3", "mp4"],
            file_type=ft.FilePickerFileType.MEDIA,
        ),
    )

    page.overlay.append(file_picker)
    page.add(ft.Row([file_picker_btn, prog_bar]))
    page.update()

if not os.environ["FLET_SECRET_KEY"]:
    os.environ["FLET_SECRET_KEY"] = os.urandom(12).hex()

app = ft.app(
    target=main, view=ft.AppView.WEB_BROWSER, port=8550, upload_dir="assets/uploads"
)
NocoleNe commented 2 months ago
        # Setting a key is required on the server side for uploading files, and I don't know what it's for!!!
        # but after set  the key,  now can upload file :)
       ` secret_key = os.getenv ( "FLET_SECRET_KEY" , default=None )
        if not secret_key:
            os.environ [ "FLET_SECRET_KEY" ] = os.urandom ( 12 ).hex ( )`
NocoleNe commented 2 months ago

I want compression image when image upload server , How to do ? which method to be call when server get the file ?