# Streamlit Keywords
[![PyPI](https://img.shields.io/pypi/v/streamlit-keywords)](https://pypi.org/project/streamlit-keywords/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/streamlit-keywords)](https://pypi.org/project/streamlit-keywords/)
![GitHub](https://img.shields.io/github/license/tahouse/streamlit-keywords)
A Streamlit custom component that provides enhanced functionality over the standard `streamlit.multiselect`. Users can enter free-form text which will appear as separate keyword chips.
**Author:** Tyler House ([@tahouse](https://github.com/tahouse))
## Demo
![Demo](https://raw.githubusercontent.com/tahouse/streamlit-keywords/main/docs/demo.gif)
## Features
- 🏷️ **Keyword Entry**: Input multiple keywords as chips/tags.
- 📝 **Free-Form Text**: Users can enter free-form text, which will be tokenized into individual keywords.
- 🎨 **Customizable**: Customize the label, placeholder text, and set a maximum number of keywords.
- 🔢 **Keyword Limit**: Optionally limit the maximum number of keywords.
- 🎨 **Theme Integration**: Automatic integration with Streamlit's theming (dark/light modes).
- 🖥️ **Seamless Integration**: Integrates seamlessly with Streamlit apps.
- 🗑️ **Keyword Removal**: Easily remove keywords by clicking the remove icon.
## Installation
```bash
pip install streamlit-keywords
```
## Usage
```python
import streamlit as st
from streamlit_keywords import keywords_input
# Create a keyword input
keywords = keywords_input(
value=["example", "keywords"],
label="Enter Keywords",
text="Type a keyword and press Enter",
max_keywords=5,
key="unique_keywords_input"
)
# Display the entered keywords
st.write("Entered keywords:", keywords)
```
## Examples
Here are some usage patterns to help you integrate `streamlit_keywords` into your Streamlit app. See `examples/example.py` for more usage examples.
### Basic Keyword Input
```python
import streamlit as st
from streamlit_keywords import keywords_input
st.title("Keyword Input Example")
keywords = keywords_input(
label="Keywords",
text="Add keywords and press Enter",
key="basic_keyword_input"
)
st.write("You have entered:", keywords)
```
### Keyword Input with Maximum Limit
```python
import streamlit as st
from streamlit_keywords import keywords_input
keywords = keywords_input(
label="Enter up to 5 keywords",
max_keywords=5,
key="keyword_input_max5"
)
st.write("Keywords:", keywords)
if keywords and len(keywords) >= 5:
st.warning("You have reached the maximum number of keywords.")
```
### Keyword Input with Default Values
```python
import streamlit as st
from streamlit_keywords import keywords_input
initial_keywords = ["Streamlit", "Python", "Data Science"]
keywords = keywords_input(
value=initial_keywords,
label="Edit your keywords",
key="keyword_input_with_defaults"
)
st.write("Current keywords:", keywords)
```
## Component API
### `keywords_input()`
Display a Streamlit component for entering keywords.
**Signature:**
```python
def keywords_input(
value: list = [],
label: str = "Keywords Input",
text: str = "Type a keyword and press Enter",
max_keywords: Optional[int] = None,
key: Optional[str] = None,
) -> List[str]:
```
**Parameters:**
- **`value`** *(List\[str\], optional)*:
Initial list of keywords. Defaults to `[]`.
- **`label`** *(str, optional)*:
Label for the input component. Defaults to `"Keywords Input"`.
- **`text`** *(str, optional)*:
Instructions or placeholder text displayed in the input field. Defaults to `"Type a keyword and press Enter"`.
- **`max_keywords`** *(Optional\[int\], optional)*:
Maximum number of keywords allowed. If `None`, there is no limit. Defaults to `None`.
- **`key`** *(str, optional)*:
An optional string to use as the unique key for the widget. It's recommended to assign a unique key to prevent the component from remounting on script reruns. Defaults to `None`.
**Returns:**
- **`List[str]`**:
A list of entered keywords.
## Development
This repository uses the Streamlit Component template system. If you want to modify or develop the component, follow these steps.
### Prerequisites
- **Python**: Version 3.7 or newer.
- **Node.js and npm**: Required for frontend development.
### Backend Development
#### Install Python Dependencies
Clone the repository and install the development dependencies.
```bash
# Clone the repository
git clone https://github.com/tahouse/streamlit-keywords.git
cd streamlit-keywords
# Install Python dependencies
pip install -e ".[devel]"
```
### Frontend Development
The frontend of this component is built using React and TypeScript, leveraging Material-UI components.
#### Install Node Dependencies
Navigate to the `streamlit_keywords/frontend` directory and install the dependencies as specified in `package.json`.
```bash
cd streamlit_keywords/frontend
npm install
```
**`package.json` dependencies:**
```json
{
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/icons-material": "^6.1.6",
"@mui/material": "^6.1.6",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"streamlit-component-lib": "^2.0.0"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@types/node": "^22.0.0",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.2",
"node": "^22.0.0",
"react-scripts": "^5.0.1",
"typescript": "^4.2.0"
}
}
```
#### Running in Development Mode
To run the component in development mode with live reloading:
1. **Start the frontend development server:**
```bash
npm start
```
This will start the React development server.
2. **Set the `_RELEASE` flag:**
Ensure that `_RELEASE = False` is set in your `__init__.py`. This tells the component to use the local development server.
3. **Run your Streamlit app:**
In a separate terminal, navigate back to the root directory and run your Streamlit app.
```bash
cd ../../
streamlit run your_app.py
```
### Building for Production
When you're ready to build the component for production:
1. **Build the frontend:**
```bash
npm run build
```
This will generate the production-ready frontend assets.
2. **Update `_RELEASE` flag:**
Set `_RELEASE = True` in `__init__.py`.
```python
_RELEASE = True
```
3. **Your component is now ready:**
The component is now ready for use in production environments.
## License
This project is licensed under the Apache License 2.0 - see the `LICENSE` file for details.
## Acknowledgemnts
This project draws inspiration from multiple sources:
- **Streamlit Multiselect**: The standard Streamlit library's multiselect component served as initial inspiration, though this project extends functionality to allow free text entry.
- **streamlit-tags**: Special thanks to Gagan Bhatia (@gagan3012) for [streamlit-tags](https://github.com/gagan3012/streamlit-tags), which was what I initially used in my application. This project addresses mobile usability limitations in streamlit-tags where the enter button functioned only as a tab key.
- **Material UI**: This component is built using [Material UI](https://mui.com/)'s Autocomplete component, which provided the foundation for the user interface.
The decision to build streamlit-keywords came from a need for a modern, mobile-friendly keyword input component with up-to-date dependencies, improved mobile user experience, and theming that closely matches Streamlit's native multiselect component.
Raw data
{
"_id": null,
"home_page": null,
"name": "streamlit-keywords",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "streamlit, component, multiselect, input, keywords, chips, material ui, tags",
"author": null,
"author_email": "Tyler House <26489166+tahouse@users.noreply.github.com>",
"download_url": "https://files.pythonhosted.org/packages/51/ba/1c1c7a4c46270fac685214c3525f8f3c27bc4f72a179dd26285eaadd51bd/streamlit_keywords-0.1.11.tar.gz",
"platform": null,
"description": "\n# Streamlit Keywords\n\n[![PyPI](https://img.shields.io/pypi/v/streamlit-keywords)](https://pypi.org/project/streamlit-keywords/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/streamlit-keywords)](https://pypi.org/project/streamlit-keywords/)\n![GitHub](https://img.shields.io/github/license/tahouse/streamlit-keywords)\n\nA Streamlit custom component that provides enhanced functionality over the standard `streamlit.multiselect`. Users can enter free-form text which will appear as separate keyword chips.\n\n**Author:** Tyler House ([@tahouse](https://github.com/tahouse))\n\n## Demo\n\n![Demo](https://raw.githubusercontent.com/tahouse/streamlit-keywords/main/docs/demo.gif)\n\n## Features\n\n- \ud83c\udff7\ufe0f **Keyword Entry**: Input multiple keywords as chips/tags.\n- \ud83d\udcdd **Free-Form Text**: Users can enter free-form text, which will be tokenized into individual keywords.\n- \ud83c\udfa8 **Customizable**: Customize the label, placeholder text, and set a maximum number of keywords.\n- \ud83d\udd22 **Keyword Limit**: Optionally limit the maximum number of keywords.\n- \ud83c\udfa8 **Theme Integration**: Automatic integration with Streamlit's theming (dark/light modes).\n- \ud83d\udda5\ufe0f **Seamless Integration**: Integrates seamlessly with Streamlit apps.\n- \ud83d\uddd1\ufe0f **Keyword Removal**: Easily remove keywords by clicking the remove icon.\n\n## Installation\n\n```bash\npip install streamlit-keywords\n```\n\n## Usage\n\n```python\nimport streamlit as st\nfrom streamlit_keywords import keywords_input\n\n# Create a keyword input\nkeywords = keywords_input(\n value=[\"example\", \"keywords\"],\n label=\"Enter Keywords\",\n text=\"Type a keyword and press Enter\",\n max_keywords=5,\n key=\"unique_keywords_input\"\n)\n\n# Display the entered keywords\nst.write(\"Entered keywords:\", keywords)\n```\n\n## Examples\n\nHere are some usage patterns to help you integrate `streamlit_keywords` into your Streamlit app. See `examples/example.py` for more usage examples.\n\n### Basic Keyword Input\n\n```python\nimport streamlit as st\nfrom streamlit_keywords import keywords_input\n\nst.title(\"Keyword Input Example\")\n\nkeywords = keywords_input(\n label=\"Keywords\",\n text=\"Add keywords and press Enter\",\n key=\"basic_keyword_input\"\n)\n\nst.write(\"You have entered:\", keywords)\n```\n\n### Keyword Input with Maximum Limit\n\n```python\nimport streamlit as st\nfrom streamlit_keywords import keywords_input\n\nkeywords = keywords_input(\n label=\"Enter up to 5 keywords\",\n max_keywords=5,\n key=\"keyword_input_max5\"\n)\n\nst.write(\"Keywords:\", keywords)\n\nif keywords and len(keywords) >= 5:\n st.warning(\"You have reached the maximum number of keywords.\")\n```\n\n### Keyword Input with Default Values\n\n```python\nimport streamlit as st\nfrom streamlit_keywords import keywords_input\n\ninitial_keywords = [\"Streamlit\", \"Python\", \"Data Science\"]\n\nkeywords = keywords_input(\n value=initial_keywords,\n label=\"Edit your keywords\",\n key=\"keyword_input_with_defaults\"\n)\n\nst.write(\"Current keywords:\", keywords)\n```\n\n## Component API\n\n### `keywords_input()`\n\nDisplay a Streamlit component for entering keywords.\n\n**Signature:**\n\n```python\ndef keywords_input(\n value: list = [],\n label: str = \"Keywords Input\",\n text: str = \"Type a keyword and press Enter\",\n max_keywords: Optional[int] = None,\n key: Optional[str] = None,\n) -> List[str]:\n```\n\n**Parameters:**\n\n- **`value`** *(List\\[str\\], optional)*: \n Initial list of keywords. Defaults to `[]`.\n\n- **`label`** *(str, optional)*: \n Label for the input component. Defaults to `\"Keywords Input\"`.\n\n- **`text`** *(str, optional)*: \n Instructions or placeholder text displayed in the input field. Defaults to `\"Type a keyword and press Enter\"`.\n\n- **`max_keywords`** *(Optional\\[int\\], optional)*: \n Maximum number of keywords allowed. If `None`, there is no limit. Defaults to `None`.\n\n- **`key`** *(str, optional)*: \n An optional string to use as the unique key for the widget. It's recommended to assign a unique key to prevent the component from remounting on script reruns. Defaults to `None`.\n\n**Returns:**\n\n- **`List[str]`**: \n A list of entered keywords.\n\n## Development\n\nThis repository uses the Streamlit Component template system. If you want to modify or develop the component, follow these steps.\n\n### Prerequisites\n\n- **Python**: Version 3.7 or newer.\n- **Node.js and npm**: Required for frontend development.\n\n### Backend Development\n\n#### Install Python Dependencies\n\nClone the repository and install the development dependencies.\n\n```bash\n# Clone the repository\ngit clone https://github.com/tahouse/streamlit-keywords.git\ncd streamlit-keywords\n\n# Install Python dependencies\npip install -e \".[devel]\"\n```\n\n### Frontend Development\n\nThe frontend of this component is built using React and TypeScript, leveraging Material-UI components.\n\n#### Install Node Dependencies\n\nNavigate to the `streamlit_keywords/frontend` directory and install the dependencies as specified in `package.json`.\n\n```bash\ncd streamlit_keywords/frontend\nnpm install\n```\n\n**`package.json` dependencies:**\n\n```json\n{\n \"dependencies\": {\n \"@emotion/react\": \"^11.13.3\",\n \"@emotion/styled\": \"^11.13.0\",\n \"@mui/icons-material\": \"^6.1.6\",\n \"@mui/material\": \"^6.1.6\",\n \"react\": \"^17.0.2\",\n \"react-dom\": \"^17.0.2\",\n \"streamlit-component-lib\": \"^2.0.0\"\n },\n \"devDependencies\": {\n \"@babel/plugin-proposal-private-property-in-object\": \"^7.21.11\",\n \"@types/node\": \"^22.0.0\",\n \"@types/react\": \"^17.0.2\",\n \"@types/react-dom\": \"^17.0.2\",\n \"node\": \"^22.0.0\",\n \"react-scripts\": \"^5.0.1\",\n \"typescript\": \"^4.2.0\"\n }\n}\n```\n\n#### Running in Development Mode\n\nTo run the component in development mode with live reloading:\n\n1. **Start the frontend development server:**\n\n ```bash\n npm start\n ```\n\n This will start the React development server.\n\n2. **Set the `_RELEASE` flag:**\n\n Ensure that `_RELEASE = False` is set in your `__init__.py`. This tells the component to use the local development server.\n\n3. **Run your Streamlit app:**\n\n In a separate terminal, navigate back to the root directory and run your Streamlit app.\n\n ```bash\n cd ../../\n streamlit run your_app.py\n ```\n\n### Building for Production\n\nWhen you're ready to build the component for production:\n\n1. **Build the frontend:**\n\n ```bash\n npm run build\n ```\n\n This will generate the production-ready frontend assets.\n\n2. **Update `_RELEASE` flag:**\n\n Set `_RELEASE = True` in `__init__.py`.\n\n ```python\n _RELEASE = True\n ```\n\n3. **Your component is now ready:**\n\n The component is now ready for use in production environments.\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the `LICENSE` file for details.\n\n## Acknowledgemnts\n\nThis project draws inspiration from multiple sources:\n\n- **Streamlit Multiselect**: The standard Streamlit library's multiselect component served as initial inspiration, though this project extends functionality to allow free text entry.\n\n- **streamlit-tags**: Special thanks to Gagan Bhatia (@gagan3012) for [streamlit-tags](https://github.com/gagan3012/streamlit-tags), which was what I initially used in my application. This project addresses mobile usability limitations in streamlit-tags where the enter button functioned only as a tab key.\n\n- **Material UI**: This component is built using [Material UI](https://mui.com/)'s Autocomplete component, which provided the foundation for the user interface.\n\nThe decision to build streamlit-keywords came from a need for a modern, mobile-friendly keyword input component with up-to-date dependencies, improved mobile user experience, and theming that closely matches Streamlit's native multiselect component.\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "A Streamlit custom component that provides enhanced usage over standard streamlit.multiselect. Users can enter free form text which will appear as separate keyword chips.",
"version": "0.1.11",
"project_urls": {
"Documentation": "https://github.com/tahouse/streamlit-keywords/blob/main/README.md",
"Homepage": "https://github.com/tahouse/streamlit-keywords",
"Issue Tracker": "https://github.com/tahouse/streamlit-keywords/issues"
},
"split_keywords": [
"streamlit",
" component",
" multiselect",
" input",
" keywords",
" chips",
" material ui",
" tags"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "6b6cc4f3fd67fc35f5f8e55ecb64306299f0fbc076ba076ec03ae6a00d1aff14",
"md5": "2698c020596754f6bd687909e12de6a0",
"sha256": "5808543ff7f3881dcee1e43e474956bc470e879d2dd4ae663d6919bef6c12d94"
},
"downloads": -1,
"filename": "streamlit_keywords-0.1.11-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2698c020596754f6bd687909e12de6a0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 800363,
"upload_time": "2025-01-26T00:37:02",
"upload_time_iso_8601": "2025-01-26T00:37:02.741415Z",
"url": "https://files.pythonhosted.org/packages/6b/6c/c4f3fd67fc35f5f8e55ecb64306299f0fbc076ba076ec03ae6a00d1aff14/streamlit_keywords-0.1.11-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "51ba1c1c7a4c46270fac685214c3525f8f3c27bc4f72a179dd26285eaadd51bd",
"md5": "634b46fa6391c28490f997dc553d649b",
"sha256": "a4c250aae035f3f713cd56f4c22778832a0aa2324eebfc79354e8831fdace9f7"
},
"downloads": -1,
"filename": "streamlit_keywords-0.1.11.tar.gz",
"has_sig": false,
"md5_digest": "634b46fa6391c28490f997dc553d649b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 796780,
"upload_time": "2025-01-26T00:37:05",
"upload_time_iso_8601": "2025-01-26T00:37:05.382203Z",
"url": "https://files.pythonhosted.org/packages/51/ba/1c1c7a4c46270fac685214c3525f8f3c27bc4f72a179dd26285eaadd51bd/streamlit_keywords-0.1.11.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-26 00:37:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tahouse",
"github_project": "streamlit-keywords",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "streamlit-keywords",
"specs": []
}
],
"lcname": "streamlit-keywords"
}