Example #1
0
    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")))
Example #2
0
    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")))
Example #3
0
    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()
Example #4
0
 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")
         ],
     )
Example #5
0
    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)
Example #7
0
    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)
Example #8
0
    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")
                ]
            ),
        )
Example #9
0
    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)
Example #12
0
#
#    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"))
Example #13
0
#    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"))