Upload Workflow Refactor (#2309)
* upload with StaticFiles * always create uploaded files folder * just use /_upload to serve uploaded files * Upload: update pyi file * app.py: only mount Upload StaticFiles if the upload component is used
This commit is contained in:
parent
3df4eac33d
commit
10e8bd010c
@ -27,6 +27,7 @@ from typing import (
|
||||
from fastapi import FastAPI, HTTPException, Request, UploadFile
|
||||
from fastapi.middleware import cors
|
||||
from fastapi.responses import StreamingResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
||||
from socketio import ASGIApp, AsyncNamespace, AsyncServer
|
||||
from starlette_admin.contrib.sqla.admin import Admin
|
||||
@ -46,7 +47,7 @@ from reflex.components.core.client_side_routing import (
|
||||
Default404Page,
|
||||
wait_for_client_redirect,
|
||||
)
|
||||
from reflex.components.core.upload import Upload
|
||||
from reflex.components.core.upload import Upload, get_uploaded_files_dir
|
||||
from reflex.components.radix import themes
|
||||
from reflex.config import get_config
|
||||
from reflex.event import Event, EventHandler, EventSpec
|
||||
@ -252,6 +253,13 @@ class App(Base):
|
||||
if Upload.is_used:
|
||||
self.api.post(str(constants.Endpoint.UPLOAD))(upload(self))
|
||||
|
||||
# To access uploaded files.
|
||||
self.api.mount(
|
||||
str(constants.Endpoint.UPLOAD),
|
||||
StaticFiles(directory=get_uploaded_files_dir()),
|
||||
name="uploaded_files",
|
||||
)
|
||||
|
||||
def add_cors(self):
|
||||
"""Add CORS middleware to the app."""
|
||||
self.api.add_middleware(
|
||||
|
@ -1,6 +1,8 @@
|
||||
"""A file upload component."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
||||
|
||||
from reflex import constants
|
||||
@ -92,6 +94,43 @@ def cancel_upload(upload_id: str) -> EventSpec:
|
||||
return call_script(f"upload_controllers[{upload_id!r}]?.abort()")
|
||||
|
||||
|
||||
def get_uploaded_files_dir() -> Path:
|
||||
"""Get the directory where uploaded files are stored.
|
||||
|
||||
Returns:
|
||||
The directory where uploaded files are stored.
|
||||
"""
|
||||
uploaded_files_dir = Path(
|
||||
os.environ.get("REFLEX_UPLOADED_FILES_DIR", "./uploaded_files")
|
||||
)
|
||||
uploaded_files_dir.mkdir(parents=True, exist_ok=True)
|
||||
return uploaded_files_dir
|
||||
|
||||
|
||||
uploaded_files_url_prefix: Var = Var.create_safe(
|
||||
"${getBackendURL(env.UPLOAD)}"
|
||||
)._replace(
|
||||
merge_var_data=VarData( # type: ignore
|
||||
imports={
|
||||
f"/{Dirs.STATE_PATH}": {imports.ImportVar(tag="getBackendURL")},
|
||||
"/env.json": {imports.ImportVar(tag="env", is_default=True)},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def get_uploaded_file_url(file_path: str) -> str:
|
||||
"""Get the URL of an uploaded file.
|
||||
|
||||
Args:
|
||||
file_path: The path of the uploaded file.
|
||||
|
||||
Returns:
|
||||
The URL of the uploaded file to be rendered from the frontend (as a str-encoded Var).
|
||||
"""
|
||||
return f"{uploaded_files_url_prefix}/{file_path}"
|
||||
|
||||
|
||||
class UploadFilesProvider(Component):
|
||||
"""AppWrap component that provides a dict of selected files by ID via useContext."""
|
||||
|
||||
|
@ -7,6 +7,8 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
||||
from reflex import constants
|
||||
from reflex.components.chakra.forms.input import Input
|
||||
@ -27,6 +29,11 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> BaseVar: ...
|
||||
@CallableEventSpec
|
||||
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
||||
def cancel_upload(upload_id: str) -> EventSpec: ...
|
||||
def get_uploaded_files_dir() -> Path: ...
|
||||
|
||||
uploaded_files_url_prefix: Var
|
||||
|
||||
def get_uploaded_file_url(file_path: str) -> str: ...
|
||||
|
||||
class UploadFilesProvider(Component):
|
||||
@overload
|
||||
|
Loading…
Reference in New Issue
Block a user