Merge remote-tracking branch 'origin/main' into reflex-0.4.0
This commit is contained in:
commit
2b7e7450f8
@ -312,7 +312,7 @@ def test_call_script(
|
|||||||
update_counter_button.click()
|
update_counter_button.click()
|
||||||
assert call_script.poll_for_value(counter, exp_not_equal="0") == "4"
|
assert call_script.poll_for_value(counter, exp_not_equal="0") == "4"
|
||||||
reset_button.click()
|
reset_button.click()
|
||||||
assert call_script.poll_for_value(counter, exp_not_equal="3") == "0"
|
assert call_script.poll_for_value(counter, exp_not_equal="4") == "0"
|
||||||
return_button.click()
|
return_button.click()
|
||||||
update_counter_button.click()
|
update_counter_button.click()
|
||||||
assert call_script.poll_for_value(counter, exp_not_equal="0") == "1"
|
assert call_script.poll_for_value(counter, exp_not_equal="0") == "1"
|
||||||
@ -330,7 +330,7 @@ def test_call_script(
|
|||||||
script,
|
script,
|
||||||
)
|
)
|
||||||
reset_button.click()
|
reset_button.click()
|
||||||
assert call_script.poll_for_value(counter, exp_not_equal="3") == "0"
|
assert call_script.poll_for_value(counter, exp_not_equal="4") == "0"
|
||||||
|
|
||||||
return_callback_button.click()
|
return_callback_button.click()
|
||||||
update_counter_button.click()
|
update_counter_button.click()
|
||||||
|
@ -27,6 +27,7 @@ from typing import (
|
|||||||
from fastapi import FastAPI, HTTPException, Request, UploadFile
|
from fastapi import FastAPI, HTTPException, Request, UploadFile
|
||||||
from fastapi.middleware import cors
|
from fastapi.middleware import cors
|
||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
||||||
from socketio import ASGIApp, AsyncNamespace, AsyncServer
|
from socketio import ASGIApp, AsyncNamespace, AsyncServer
|
||||||
from starlette_admin.contrib.sqla.admin import Admin
|
from starlette_admin.contrib.sqla.admin import Admin
|
||||||
@ -46,7 +47,7 @@ from reflex.components.core.client_side_routing import (
|
|||||||
Default404Page,
|
Default404Page,
|
||||||
wait_for_client_redirect,
|
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.components.radix import themes
|
||||||
from reflex.config import get_config
|
from reflex.config import get_config
|
||||||
from reflex.event import Event, EventHandler, EventSpec
|
from reflex.event import Event, EventHandler, EventSpec
|
||||||
@ -252,6 +253,13 @@ class App(Base):
|
|||||||
if Upload.is_used:
|
if Upload.is_used:
|
||||||
self.api.post(str(constants.Endpoint.UPLOAD))(upload(self))
|
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):
|
def add_cors(self):
|
||||||
"""Add CORS middleware to the app."""
|
"""Add CORS middleware to the app."""
|
||||||
self.api.add_middleware(
|
self.api.add_middleware(
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
"""A file upload component."""
|
"""A file upload component."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Optional, Union
|
||||||
|
|
||||||
from reflex import constants
|
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()")
|
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):
|
class UploadFilesProvider(Component):
|
||||||
"""AppWrap component that provides a dict of selected files by ID via useContext."""
|
"""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.vars import Var, BaseVar, ComputedVar
|
||||||
from reflex.event import EventChain, EventHandler, EventSpec
|
from reflex.event import EventChain, EventHandler, EventSpec
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Optional, Union
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.components.chakra.forms.input import Input
|
from reflex.components.chakra.forms.input import Input
|
||||||
@ -27,6 +29,11 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> BaseVar: ...
|
|||||||
@CallableEventSpec
|
@CallableEventSpec
|
||||||
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
||||||
def cancel_upload(upload_id: str) -> 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):
|
class UploadFilesProvider(Component):
|
||||||
@overload
|
@overload
|
||||||
|
Loading…
Reference in New Issue
Block a user