[REF-3016] Allow special characters in upload ID (#3449)

This commit is contained in:
Elijah Ahianyo 2024-06-12 09:21:21 -07:00 committed by GitHub
parent c3c06a1fcb
commit 8c8156f3aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 65 additions and 10 deletions

View File

@ -50,10 +50,18 @@ def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> BaseVar:
Returns: Returns:
A var referencing the file upload drop trigger. A var referencing the file upload drop trigger.
""" """
id_var = Var.create_safe(id_, _var_is_string=True)
var_name = f"""e => setFilesById(filesById => {{
const updatedFilesById = Object.assign({{}}, filesById);
updatedFilesById[{id_var._var_name_unwrapped}] = e;
return updatedFilesById;
}})
"""
return BaseVar( return BaseVar(
_var_name=f"e => setFilesById(filesById => ({{...filesById, {id_}: e}}))", _var_name=var_name,
_var_type=EventChain, _var_type=EventChain,
_var_data=upload_files_context_var_data, _var_data=VarData.merge(upload_files_context_var_data, id_var._var_data),
) )
@ -67,10 +75,11 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> BaseVar:
Returns: Returns:
A var referencing the list of selected file paths. A var referencing the list of selected file paths.
""" """
id_var = Var.create_safe(id_, _var_is_string=True)
return BaseVar( return BaseVar(
_var_name=f"(filesById.{id_} ? filesById.{id_}.map((f) => (f.path || f.name)) : [])", _var_name=f"(filesById[{id_var._var_name_unwrapped}] ? filesById[{id_var._var_name_unwrapped}].map((f) => (f.path || f.name)) : [])",
_var_type=List[str], _var_type=List[str],
_var_data=upload_files_context_var_data, _var_data=VarData.merge(upload_files_context_var_data, id_var._var_data),
) )
@ -99,7 +108,9 @@ def cancel_upload(upload_id: str) -> EventSpec:
Returns: Returns:
An event spec that cancels the upload when triggered. An event spec that cancels the upload when triggered.
""" """
return call_script(f"upload_controllers[{upload_id!r}]?.abort()") return call_script(
f"upload_controllers[{Var.create_safe(upload_id, _var_is_string=True)._var_name_unwrapped!r}]?.abort()"
)
def get_upload_dir() -> Path: def get_upload_dir() -> Path:

View File

@ -386,12 +386,12 @@ class FileUpload(Base):
) )
upload_id = self.upload_id or DEFAULT_UPLOAD_ID upload_id = self.upload_id or DEFAULT_UPLOAD_ID
spec_args = [ spec_args = [
( (
Var.create_safe("files", _var_is_string=False), Var.create_safe("files", _var_is_string=False),
Var.create_safe( Var.create_safe(
f"filesById.{upload_id}", _var_is_string=False f"filesById[{Var.create_safe(upload_id, _var_is_string=True)._var_name_unwrapped}]",
_var_is_string=False,
)._replace(_var_data=upload_files_context_var_data), )._replace(_var_data=upload_files_context_var_data),
), ),
( (

View File

@ -39,6 +39,19 @@ def upload_component():
return upload_component() return upload_component()
@pytest.fixture
def upload_component_id_special():
def upload_component():
return rx.upload(
rx.button("select file"),
rx.text("Drag and drop files here or click to select files"),
border="1px dotted black",
id="#spec!`al-_98ID",
)
return upload_component()
@pytest.fixture @pytest.fixture
def upload_component_with_props(): def upload_component_with_props():
"""A test upload component with props function. """A test upload component with props function.
@ -72,7 +85,12 @@ def test_upload_root_component_render(upload_root_component):
assert upload["props"] == [ assert upload["props"] == [
"id={`default`}", "id={`default`}",
"multiple={true}", "multiple={true}",
"onDrop={e => setFilesById(filesById => ({...filesById, default: e}))}", "onDrop={e => setFilesById(filesById => {\n"
" const updatedFilesById = Object.assign({}, filesById);\n"
" updatedFilesById[`default`] = e;\n"
" return updatedFilesById;\n"
" })\n"
" }",
"ref={ref_default}", "ref={ref_default}",
] ]
assert upload["args"] == ("getRootProps", "getInputProps") assert upload["args"] == ("getRootProps", "getInputProps")
@ -114,7 +132,12 @@ def test_upload_component_render(upload_component):
assert upload["props"] == [ assert upload["props"] == [
"id={`default`}", "id={`default`}",
"multiple={true}", "multiple={true}",
"onDrop={e => setFilesById(filesById => ({...filesById, default: e}))}", "onDrop={e => setFilesById(filesById => {\n"
" const updatedFilesById = Object.assign({}, filesById);\n"
" updatedFilesById[`default`] = e;\n"
" return updatedFilesById;\n"
" })\n"
" }",
"ref={ref_default}", "ref={ref_default}",
] ]
assert upload["args"] == ("getRootProps", "getInputProps") assert upload["args"] == ("getRootProps", "getInputProps")
@ -156,6 +179,27 @@ def test_upload_component_with_props_render(upload_component_with_props):
"maxFiles={2}", "maxFiles={2}",
"multiple={true}", "multiple={true}",
"noDrag={true}", "noDrag={true}",
"onDrop={e => setFilesById(filesById => ({...filesById, default: e}))}", "onDrop={e => setFilesById(filesById => {\n"
" const updatedFilesById = Object.assign({}, filesById);\n"
" updatedFilesById[`default`] = e;\n"
" return updatedFilesById;\n"
" })\n"
" }",
"ref={ref_default}", "ref={ref_default}",
] ]
def test_upload_component_id_with_special_chars(upload_component_id_special):
upload = upload_component_id_special.render()
assert upload["props"] == [
r"id={`#spec!\`al-_98ID`}",
"multiple={true}",
"onDrop={e => setFilesById(filesById => {\n"
" const updatedFilesById = Object.assign({}, filesById);\n"
" updatedFilesById[`#spec!\\`al-_98ID`] = e;\n"
" return updatedFilesById;\n"
" })\n"
" }",
"ref={ref__spec_al__98ID}",
]