{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import io\n", "\n", "import panel as pn\n", "import panel_material_ui as pmui\n", "\n", "pn.extension(\"tabulator\", \"codeeditor\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `FileInput` widget empowers you to seamlessly upload one or more files from the frontend, making filename, file data, and [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) instantly available in Python. For handling large files efficiently, we recommend using the [`FileDropper`](https://panel.holoviz.org/reference/widgets/FileDropper.html) widget instead.\n", "\n", "#### Parameters\n", "\n", "For comprehensive customization options, explore our [customization guides](https://panel-material-ui.holoviz.org/customization/index.html).\n", "\n", "##### Core Parameters\n", "\n", "* **`accept`** (str): Define accepted file types using MIME types (e.g., 'image/png') or extensions (e.g., '.png') as a comma-separated list\n", "* **`chunk_size`** (int): Size in bytes per chunk transferred across the WebSocket (`default=10000000`, i.e. 10MB).\n", "* **`directory`** (bool): Enable directory upload when set to `True`, allowing users to select entire folders\n", "* **`filename`** (str/list): Access the filename(s) of uploaded file(s)\n", "* **`max_file_size`** (str): Maximum size of a file as a string with units given in KB or MB, e.g. 5MB or 750KB.\n", "* **`max_files`** (int): Maximum number of files that can be uploaded if `multiple=True`.\n", "* **`max_total_file_size`** (str): Maximum size of all uploaded files, as a string with units given in KB or MB, e.g. 5MB or 750KB.\n", "* **`mime_type`** (str/list): Retrieve the MIME type(s) of uploaded file(s)\n", "* **`multiple`** (bool): Allow multiple file selection when enabled\n", "* **`value`** (bytes/list): Contains file data as bytes object(s) - single object or list depending on `multiple` setting\n", "\n", "#### Available Methods\n", "\n", "* **`save()`**: Persist the uploaded data to a file or `BytesIO` object\n", "* **`clear()`**: Reset all file-related parameters (`value`, `filename`, `mime_type`) to their default state\n", "* **`object()`**: Intelligent conversion of uploaded files to appropriate Python objects (e.g., CSV → pandas DataFrame)\n", "* **`view()`**: Automatically display uploaded content using the most suitable visualization component\n", "___" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Getting Started with FileInput\n", "\n", "Let's begin with a simple example to see the `FileInput` widget in action:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "file_input = pmui.FileInput()\n", "\n", "file_input" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**💡 Pro tip:** The `FileInput` widget supports intuitive **drag and drop** functionality - simply drag files directly onto the upload button!\n", "\n", "**Accessing your uploaded content** is straightforward. The `value` parameter contains a [bytestring](https://docs.python.org/3/library/stdtypes.html#bytes-objects) with your file's contents, while the `mime_type` parameter provides the file type information in standard MIME format (e.g., `image/png`, `text/csv`)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "file_input.value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Explore the key parameters** below - `value`, `filename`, and `mime_type` work together to give you complete information about uploaded files:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pmui.FlexBox(file_input.param.value, file_input.param.filename, file_input.param.mime_type)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**🎯 Try it yourself!** Upload a file above and watch the parameters update in real-time." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Saving Uploaded Files\n", "\n", "Once you've received a file upload, the built-in `save()` method makes it easy to persist the data. You can save to either a file on disk or a [BytesIO](https://docs.python.org/3/library/io.html#binary-i-o) object for in-memory processing:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# File\n", "if file_input.value is not None:\n", " file_input.save('test.png')\n", "\n", "# BytesIO object\n", "if file_input.value is not None:\n", " out = io.BytesIO()\n", " file_input.save(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Controlling File Types with Smart Filtering\n", "\n", "The `accept` parameter gives you precise control over which files users can select. Using standard HTML file input patterns, you can specify:\n", "\n", "**File Extensions:**\n", "* `.gif, .jpg, .png, .doc` - Specific file extensions are selectable\n", "\n", "**Media Categories:**\n", "* `audio/*` - All audio files (MP3, WAV, etc.)\n", "* `video/*` - All video files (MP4, AVI, etc.)\n", "* `image/*` - All image files (PNG, JPEG, etc.)\n", "\n", "**MIME Types:**\n", "* Any valid [IANA Media Type](https://www.iana.org/assignments/media-types/media-types.xhtml) for precise control\n", "\n", "**Example:** Restrict to data files only:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pmui.FileInput(accept='.csv,.json')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Handling Multiple Files and Directories\n", "\n", "**Scale up your file handling** with these powerful options:\n", "- Set `multiple=True` to allow users to select several files at once\n", "- Use `directory=True` to enable entire folder uploads\n", "\n", "Here's how to accept multiple PNG files:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pmui.FileInput(accept='.png', multiple=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Important:** When `multiple=True` or `directory=True` is enabled, the `value`, `filename` and `mime_type` parameters automatically become lists, making it easy to iterate through all uploaded files." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Resetting the FileInput\n", "\n", "Need a fresh start? The `clear()` method instantly resets all file-related parameters to their default values:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# file_input.clear()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Intelligent File Object Conversion\n", "\n", "The `FileInput.object` property is your gateway to working with uploaded files as native Python objects. This smart feature automatically converts files based on their type:\n", "\n", "**Automatic Conversions:**\n", "- 📊 CSV files → pandas `DataFrame`\n", "- 🗂️ JSON files → Python `dict`\n", "- 🖼️ Images → PIL `Image` objects\n", "- 📄 And many more!\n", "\n", "**Try it below** - upload different file types and see the magic happen:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "file_input = pmui.FileInput(accept='.csv,.json,.png,.mp3,.mp4')\n", "pmui.Column(file_input, file_input.object)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Pro tip:** When you know your uploaded file will become a `DataFrame`, you can customize its display using Panel's visualization components:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "file_input = pmui.FileInput(accept='.csv,.xlsx')\n", "pmui.Column(file_input, pn.widgets.Tabulator(value=file_input.object, height=200, width=500))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Automatic Content Visualization\n", "\n", "The `view()` method takes the guesswork out of displaying uploaded files by automatically choosing the best visualization component for each file type:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import panel_material_ui as pmui\n", "import panel as pn\n", "\n", "pn.extension(\"tabulator\", \"codeeditor\") # You must manually configure the possible extensions needed depending on the `accept` value.\n", "\n", "file_input = pmui.FileInput(\n", " label=\"Upload an image\",\n", " accept=\".csv,.xlsx,.png,.jpg,.jpeg,.json,.mp3,.mp4,.pdf\",\n", " multiple=True,\n", ")\n", "\n", "pmui.Column(file_input, file_input.view(height=300, width=500))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In addition to converting the `value` to a displayable `object` it also picks an appropriate component to display the `object` with based on the `mime_type`.\n", "\n", "**How it works:** The method intelligently converts your uploaded `value` to a displayable `object`, then selects the most appropriate display component based on the file's `mime_type`.\n", "\n", "**Customization Options:**\n", "\n", "- **`object_if_no_value`**: Choose what to display when no files are uploaded (defaults to invisible layout)\n", "- **`layout`**: Specify how multiple files are organized (defaults to `panel_material_ui.Tabs`)\n", "- **`**kwargs`**: Pass styling options like `height`, `width`, and `sizing_mode` to the layout\n", "\n", "**The result?** Professional-looking file previews with zero configuration!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Real-World Example: CSV Data Explorer\n", "\n", "Here's a practical example showing how to build a custom CSV file processor. This app demonstrates advanced file handling with custom conversion logic:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import panel_material_ui as pmui\n", "import panel as pn\n", "import io\n", "import pandas as pd\n", "import io\n", "\n", "pn.extension(\"tabulator\")\n", "\n", "file_input = pmui.FileInput(\n", " label=\"Upload a CSV file\",\n", " accept=\".csv\",\n", " color=\"success\",\n", " variant=\"outlined\",\n", ")\n", "\n", "def csv_to_pandas(value):\n", " \"\"\"Convert uploaded CSV file to a pandas DataFrame.\"\"\"\n", " if value:\n", " return pd.read_csv(io.BytesIO(value))\n", " return pd.DataFrame()\n", "\n", "df = pn.bind(csv_to_pandas, file_input)\n", "\n", "pmui.Column(file_input, pn.widgets.Tabulator(value=df, height=300, width=800))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Real-World Example: Image Viewer\n", "\n", "Build a sleek image viewer that handles multiple formats with graceful fallbacks. This example shows how to create custom processing functions for specialized file types:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import panel_material_ui as pmui\n", "import panel as pn\n", "from PIL import Image\n", "import io\n", "\n", "pn.extension()\n", "\n", "file_input = pmui.FileInput(\n", " label=\"Upload an image\",\n", " accept=\".png, .jpg, .jpeg\",\n", " multiple=False,\n", ")\n", "\n", "def image_view(value):\n", " \"\"\"Callback function to handle image upload.\"\"\"\n", " if value:\n", " image = Image.open(io.BytesIO(value))\n", " return pn.pane.Image(image, height=250)\n", " return \"No Image\"\n", "\n", "file_view = pn.bind(image_view, file_input)\n", "\n", "pmui.Column(file_input, file_view)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## API\n", "\n", "### Parameters" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "file_input.api(jslink=True)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.9" } }, "nbformat": 4, "nbformat_minor": 4 }