def test_delete_file_across_sessions(self): """Deleting file param mismatch should fail with 404 status.""" file1 = UploadedFile("1234", "name", "type", b"1234") file2 = UploadedFile("4567", "name", "type", b"1234") self.file_mgr.add_files("session1", "widget1", [file1]) self.file_mgr.add_files("session2", "widget2", [file2]) response = self.fetch(f"/upload_file/session2/widget1/1234", method="DELETE") self.assertEqual(404, response.code) self.assertTrue(len(self.file_mgr.get_files("session1", "widget1"))) self.assertTrue(len(self.file_mgr.get_files("session2", "widget2")))
def test_delete_file(self): """File should be able to be deleted successfully""" file1 = UploadedFile("1234", "name", "type", b"1234") file2 = UploadedFile("4567", "name", "type", b"1234") self.file_mgr.add_files("session1", "widget1", [file1]) self.file_mgr.add_files("session2", "widget2", [file2]) response = self.fetch(f"/upload_file/session1/widget1/1234", method="DELETE") self.assertEqual(200, response.code) self.assertFalse(len(self.file_mgr.get_files("session1", "widget1"))) self.assertTrue(len(self.file_mgr.get_files("session2", "widget2")))
def test_uploaded_file_triggers_rerun(self): """Uploading a file should trigger a re-run in the associated ReportSession.""" with self._patch_report_session(): yield self.start_server_loop() # Connect twice and get associated ReportSessions yield self.ws_connect() yield self.ws_connect() session_info1 = list(self.server._session_info_by_id.values())[0] session_info2 = list(self.server._session_info_by_id.values())[1] file = UploadedFile("file.txt", b"123") # "Upload a file" for Session1 self.server._uploaded_file_mgr.add_files( session_id=session_info1.session.id, widget_id="widget_id", files=[file], ) self.assertEqual( self.server._uploaded_file_mgr.get_files( session_info1.session.id, "widget_id"), [file], ) # Session1 should have a rerun request; Session2 should not session_info1.session.request_rerun.assert_called_once() session_info2.session.request_rerun.assert_not_called()
def test_upload_one_file(self): """Uploading a file should populate our file_mgr.""" file = UploadedFile("id", "image.png", "type", b"123") params = { file.name: file, "sessionId": (None, "fooReport"), "widgetId": (None, "barWidget"), } response = self._upload_files(params) self.assertEqual(200, response.code) self.assertEqual( [file.getvalue()], [ file.getvalue() for file in self.file_mgr.get_files("fooReport", "barWidget") ], )
def test_upload_multiple_files(self): file1 = UploadedFile("image1.png", b"123") file2 = UploadedFile("image2.png", b"456") file3 = UploadedFile("image3.png", b"789") params = { file1.name: file1, file2.name: file2, file3.name: file3, "sessionId": (None, "fooReport"), "widgetId": (None, "barWidget"), } response = self._upload_files(params) self.assertEqual(200, response.code) self.assertEqual( sorted([file1, file2, file3], key=_get_filename), sorted(self.file_mgr.get_files("fooReport", "barWidget"), key=_get_filename), )
def post(self): args = {} # type: Dict[str, List[bytes]] files = {} # type: Dict[str, List[Any]] tornado.httputil.parse_body_arguments( content_type=self.request.headers["Content-Type"], body=self.request.body, arguments=args, files=files, ) try: session_id = self._require_arg(args, "sessionId") widget_id = self._require_arg(args, "widgetId") except Exception as e: self.send_error(400, reason=str(e)) return LOGGER.debug( f"{len(files)} file(s) received for session {session_id} widget {widget_id}" ) # Create an UploadedFile object for each file. uploaded_files = [] for id, flist in files.items(): for file in flist: uploaded_files.append( UploadedFile( id=id, name=file["filename"], type=file["content_type"], data=file["body"], )) if len(uploaded_files) == 0: self.send_error(400, reason="Expected at least 1 file, but got 0") return replace = self.get_argument("replace", "false") update_files = (self._file_mgr.replace_files if replace == "true" else self._file_mgr.add_files) update_files( session_id=session_id, widget_id=widget_id, files=uploaded_files, ) LOGGER.debug( f"{len(files)} file(s) uploaded for session {session_id} widget {widget_id}. replace {replace}" ) self.set_status(200)
def test_multiple_files(self, get_files_patch): """Test the accept_multiple_files flag""" files = [ UploadedFile("id1", "file1", "type", b"123"), UploadedFile("id2", "file2", "type", b"456"), ] get_files_patch.return_value = files for accept_multiple in [True, False]: return_val = st.file_uploader( "label", type="png", accept_multiple_files=accept_multiple) c = self.get_delta_from_queue().new_element.file_uploader self.assertEqual(accept_multiple, c.multiple_files) # If "accept_multiple_files" is True, then we should get a list of values # back. Otherwise, we should just get a single value. if accept_multiple: self.assertEqual(files, return_val) else: self.assertEqual(files[0], return_val)
def test_upload_multiple_files(self): file1 = UploadedFile("id1", "image1.png", "type", b"123") file2 = UploadedFile("id2", "image2.png", "type", b"456") file3 = UploadedFile("id3", "image3.png", "type", b"789") params = { file1.name: file1, file2.name: file2, file3.name: file3, "sessionId": (None, "fooReport"), "widgetId": (None, "barWidget"), "totalFiles": (None, "1"), } response = self._upload_files(params) self.assertEqual(200, response.code) self.assertEqual( sorted([file1.name, file2.name, file3.name]), sorted( [ file.name for file in self.file_mgr.get_files("fooReport", "barWidget") ] ), )
def test_orphaned_upload_file_deletion(self): """An uploaded file with no associated ReportSession should be deleted.""" with self._patch_report_session(): yield self.start_server_loop() yield self.ws_connect() # "Upload a file" for a session that doesn't exist self.server._uploaded_file_mgr.add_files( session_id="no_such_session", widget_id="widget_id", files=[UploadedFile("file.txt", b"123")], ) self.assertIsNone( self.server._uploaded_file_mgr.get_files( "no_such_session", "widget_id"))
def import_bytes(kiara: Kiara, uploaded_file: UploadedFile): with tempfile.TemporaryDirectory() as tmpdirname: path = os.path.join(tmpdirname, uploaded_file.name) with open(path, "wb") as f: f.write(uploaded_file.getbuffer()) if uploaded_file.name.endswith(".csv"): kiara.run( "table.import.from_local_file", inputs={ "path": path, "aliases": [uploaded_file.name[0:-4]], "file_aliases": [uploaded_file.name], }, ) else: kiara.run( "import.local_file", inputs={"path": path, "aliases": [uploaded_file.name]}, )
def post(self): args = {} # type: Dict[str, List[bytes]] files = {} # type: Dict[str, List[Any]] tornado.httputil.parse_body_arguments( content_type=self.request.headers["Content-Type"], body=self.request.body, arguments=args, files=files, ) try: session_id = self._require_arg(args, "sessionId") widget_id = self._require_arg(args, "widgetId") except Exception as e: self.send_error(400, reason=str(e)) return # Create an UploadedFile object for each file. uploaded_files = [] for flist in files.values(): # Because multiple files with the same name can be uploaded, each # entry in the files dict is itself a list. for file in flist: uploaded_files.append( UploadedFile(name=file["filename"], data=file["body"])) if len(uploaded_files) == 0: self.send_error(400, reason="Expected at least 1 file, but got 0") return self._file_mgr.add_files( session_id=session_id, widget_id=widget_id, files=uploaded_files, ) self.set_status(200)
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for UploadedFileManager""" import unittest from streamlit.uploaded_file_manager import UploadedFile from streamlit.uploaded_file_manager import UploadedFileManager file1 = UploadedFile(id="id1", name="file1", type="type", data=b"file1") file2 = UploadedFile(id="id2", name="file2", type="type", data=b"file2") class UploadedFileManagerTest(unittest.TestCase): def setUp(self): self.mgr = UploadedFileManager() self.filemgr_events = [] self.mgr.on_files_updated.connect(self._on_files_updated) def _on_files_updated(self, file_list, **kwargs): self.filemgr_events.append(file_list) def test_add_file(self): self.assertIsNone(self.mgr.get_files("non-report", "non-widget"))
# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for UploadedFileManager""" import unittest from streamlit.uploaded_file_manager import UploadedFile from streamlit.uploaded_file_manager import UploadedFileList from streamlit.uploaded_file_manager import UploadedFileManager file1 = UploadedFile(name="file1", data=b"file1") file2 = UploadedFile(name="file2", data=b"file2") class UploadedFileManagerTest(unittest.TestCase): def setUp(self): self.mgr = UploadedFileManager() self.filemgr_events = [] self.mgr.on_files_added.connect(self._on_files_added) def _on_files_added(self, file_list, **kwargs): self.filemgr_events.append(file_list) def test_add_file(self): self.assertIsNone(self.mgr.get_files("non-report", "non-widget"))