Repository: arnaudmiribel/streamlit-extras

Issue:
Separate gallery from package
Could have two folders, one for actual extras, one for the gallery app (and the gallery app could have a separate, tighter set of dependencies).

That way we can have much looser requirements on the package itself.

Discussion:

Patch:
diff --git a/.gitignore b/.gitignore
index 6769e21..f875d65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -157,4 +157,6 @@ cython_debug/
 #  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
 #  and can be added to the global gitignore or merged into this file.  For a more nuclear
 #  option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
\ No newline at end of file
+#.idea/
+
+.DS_Store
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..a7c761e
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,57 @@
+# 🙋 Contribute
+
+Head over to our public [repository](https://github.com/arnaudmiribel/streamlit-extras) and:
+
+- Create an empty directory for your extra in the `extras/` directory
+- Add a `__init__.py` file to give in some metadata so we can automatically showcase your extra in the hub!
+
+  - If your function is new, and doesn't yet exist on PyPi, here's an example of how to add it:
+
+    ```python
+    # extras/<extra_name>/__init__.py
+
+    def my_main_function():
+        ...
+
+    def example():
+        ...
+
+    __func__ = my_main_function  # main function of your extra!
+    __title__ = "Great title!"  # title of your extra!
+    __desc__ = "Great description"  # description of your extra!
+    __icon__ = "🔭"  # give your extra an icon!
+    __examples__ = [example]  # create some examples to show how cool your extra is!
+    __author__ = "Eva Jensen"
+    __experimental_playground__ = False # Optional
+    ```
+
+  - If your extra already exists on github and pypi:
+
+    ```python
+    # extras/<extra_name>/__init__.py
+
+    from my_package import my_main_function
+
+    def example():
+        ...
+
+    __func__ = my_main_function  # main function of your extra!
+    __title__ = "Great title!"  # title of your extra!
+    __desc__ = "Great description"  # description of your extra!
+    __icon__ = "🔭"  # give your extra an icon!
+    __examples__ = [example]  # create some examples to show how cool your extra is!
+    __author__ = "Eva Jensen"
+    __pypi_name__ = "my-cool-package"
+    __package_name__ = "my_package"
+    __github_repo__ = "evajensen/my-repo" # Optional
+    __streamlit_cloud_url__ = "http://my-super-app.streamlitapp.com" # Optional
+    __experimental_playground__ = False # Optional
+    ```
+
+    Then add `my_package` to the list of `dependencies` in `pyproject.toml`
+
+- If you'd like to test that your package has all the required fields, you can run `poetry run pytest` from the repository
+- You can set up linting to standardize your code by running `pre-commit install`, which will then check the formatting of the files you added
+- Submit a PR!
+
+If you are having troubles, create an issue on the repo or [DM me on Twitter](https://twitter.com/arnaudmiribel)!
diff --git a/gallery/requirements.txt b/gallery/requirements.txt
new file mode 100644
index 0000000..05dedd5
--- /dev/null
+++ b/gallery/requirements.txt
@@ -0,0 +1,2 @@
+streamlit==1.12.2
+streamlit-extras
\ No newline at end of file
diff --git a/streamlit_app.py b/gallery/streamlit_app.py
similarity index 86%
rename from streamlit_app.py
rename to gallery/streamlit_app.py
index d9025b3..2fa56c6 100644
--- a/streamlit_app.py
+++ b/gallery/streamlit_app.py
@@ -1,4 +1,5 @@
 import inspect
+import pkgutil
 import random
 from importlib import import_module
 from itertools import cycle, dropwhile
@@ -6,6 +7,8 @@ from pathlib import Path
 from typing import Callable, List, Optional
 
 import streamlit_patches as st
+
+import streamlit_extras
 from streamlit_extras.badges import badge
 from streamlit_extras.function_explorer import function_explorer
 from streamlit_extras.switch_page_button import switch_page
@@ -64,40 +67,9 @@ Learn more about the library on [GitHub](https://www.github.com/arnaudmiribel/st
 
 
 def contribute():
-    st.title("🙋 Contribute")
-    st.write(
-        """
-Head over to our public [repository](https://github.com/arnaudmiribel/streamlit-extras) and:
-- Create an empty directory for your extra in the `extras/` directory
-- Add a `__init__.py` file to give in some metadata so we can automatically showcase your extra in the hub! Here's an example:
-
-```
-# __init__.py
-
-def my_main_function():
-    pass
-
-def example():
-    pass
-
-__func__ = my_main_function  # main function of your extra!
-__title__ = "Great title!"  # title of your extra!
-__desc__ = "Great description"  # description of your extra!
-__icon__ = "🔭"  # give your extra an icon!
-__examples__ = [example]  # create some examples to show how cool your extra is!
-__author__ = "Eva Jensen"
-__github_repo__ = "evajensen/my-repo"
-__streamlit_cloud_url__ = "http://my-super-app.streamlitapp.com"
-__pypi_name__ = ...
-__experimental_playground__ = False
-
-```
-- Submit a PR!
-
-
-If you are having troubles, create an issue on the repo or [DM me on Twitter](https://twitter.com/arnaudmiribel)!
-"""
-    )
+    path = (Path(__file__) / "../../CONTRIBUTING.md").resolve()
+    content = path.read_text()
+    st.write(content)
 
 
 def waiting_list():
@@ -139,12 +111,8 @@ def get_empty():
 
 st.page(get_empty, "  ", " ")
 
-PATH_TO_EXTRAS = "streamlit_extras"
-extra_names = [
-    folder.name
-    for folder in Path(PATH_TO_EXTRAS).glob("*")
-    if folder.is_dir() and folder.name != "__pycache__"
-]
+
+extra_names = [extra.name for extra in pkgutil.iter_modules(streamlit_extras.__path__)]
 
 
 def get_page_content(
@@ -245,7 +213,7 @@ def get_page_content(
 settings = dict()
 
 for extra_name in extra_names:
-    mod = import_module(f"{PATH_TO_EXTRAS}.{extra_name}")
+    mod = import_module(f"streamlit_extras.{extra_name}")
     title = mod.__title__
     icon = mod.__icon__
     func = mod.__func__
diff --git a/streamlit_patches.py b/gallery/streamlit_patches.py
similarity index 99%
rename from streamlit_patches.py
rename to gallery/streamlit_patches.py
index a02e15c..b43f43f 100644
--- a/streamlit_patches.py
+++ b/gallery/streamlit_patches.py
@@ -73,7 +73,7 @@ def page(
     """
 
     # TODO -- FIX THIS
-    main_script_path = "streamlit_app.py"
+    main_script_path = "gallery/streamlit_app.py"
 
     main_page_hash = calc_md5(main_script_path)
 
diff --git a/poetry.lock b/poetry.lock
index 3bbd20b..7d61c6d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -573,7 +573,7 @@ htbuilder = "*"
 
 [[package]]
 name = "streamlit"
-version = "1.12.2"
+version = "1.13.0"
 description = "The fastest way to build data apps in Python"
 category = "main"
 optional = false
@@ -590,7 +590,7 @@ numpy = "*"
 packaging = ">=14.1"
 pandas = ">=0.21.0"
 pillow = ">=6.2.0"
-protobuf = ">=3.12,<4"
+protobuf = ">=3.12,<3.20.2 || >3.20.2,<4"
 pyarrow = ">=4.0"
 pydeck = ">=0.1.dev5"
 pympler = ">=0.9"
@@ -745,7 +745,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
 [metadata]
 lock-version = "1.1"
 python-versions = ">=3.9,<3.9.7 || >3.9.7,<4.0" # Apparently streamlit doesn't work with 3.9.7
-content-hash = "0aab468398ce4bfc5816f9a1dc0c1fb00c860ab63ab889132e552e7db6da2ff0"
+content-hash = "93ba29095b7aa97a2092dcbfcd314d9ca56de54c04a5e8b1e29de8e0ee7ceefd"
 
 [metadata.files]
 altair = [
@@ -1232,8 +1232,8 @@ st-annotated-text = [
     {file = "st-annotated-text-3.0.0.tar.gz", hash = "sha256:b63a55ef03411ce4e37bf9269a32e6ee4b344a658552e3fb0b4924bca0c5dc40"},
 ]
 streamlit = [
-    {file = "streamlit-1.12.2-py2.py3-none-any.whl", hash = "sha256:c56d0775feb39116ff90a8b01ee15be27212ee50abb88943607205d26d1d9923"},
-    {file = "streamlit-1.12.2.tar.gz", hash = "sha256:f0461bebd6c1b58c38f0f602ee9bb6699f66dfe14fd2e05abc25ebe96ff4ba21"},
+    {file = "streamlit-1.13.0-py2.py3-none-any.whl", hash = "sha256:3231a6f424f8a7f365dc9e46d4fbb66a3634fd570c74769b8a69f792d9285d3a"},
+    {file = "streamlit-1.13.0.tar.gz", hash = "sha256:eb178dc87d9f01e2be11ee9e4d55f79a678597ece56cacbfe5a9236d768d48da"},
 ]
 streamlit-embedcode = [
     {file = "streamlit-embedcode-0.1.2.tar.gz", hash = "sha256:22a50eb43407bab3d0ed2d4b58e89819da477cd0592ef87edbd373c286712e3a"},
diff --git a/pyproject.toml b/pyproject.toml
index a41271a..0f174ac 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,12 +4,13 @@ build-backend = "poetry.core.masonry.api"
 
 [tool.poetry]
 name = "streamlit-extras"
-version = "0.1.1"
+version = "0.1.2"
 license = "Apache 2.0"
 description = "A library to discover, try, install and share Streamlit extras"
 authors = ["Arnaud Miribel <arnaudmiribel@gmail.com>"]
 readme = "README.md"
-packages = [{include = "streamlit_extras"}]
+packages = [{include = "streamlit_extras", from = "src"}]
+exclude = ["gallery/"]
 keywords = [
     "python",
     "streamlit",
@@ -19,7 +20,7 @@ keywords = [
 
 [tool.poetry.dependencies]
 python = ">=3.9,<3.9.7 || >3.9.7,<4.0" # Apparently streamlit doesn't work with 3.9.7
-streamlit = "^1.12.2"
+streamlit = ">=1.0.0"
 htbuilder = "^0.6.0"
 st-annotated-text = "^3.0.0"
 streamlit-embedcode = "^0.1.2"
diff --git a/streamlit_extras/__init__.py b/src/streamlit_extras/__init__.py
similarity index 100%
rename from streamlit_extras/__init__.py
rename to src/streamlit_extras/__init__.py
diff --git a/streamlit_extras/annotated_text/__init__.py b/src/streamlit_extras/annotated_text/__init__.py
similarity index 100%
rename from streamlit_extras/annotated_text/__init__.py
rename to src/streamlit_extras/annotated_text/__init__.py
diff --git a/streamlit_extras/app_logo/__init__.py b/src/streamlit_extras/app_logo/__init__.py
similarity index 100%
rename from streamlit_extras/app_logo/__init__.py
rename to src/streamlit_extras/app_logo/__init__.py
diff --git a/streamlit_extras/badges/__init__.py b/src/streamlit_extras/badges/__init__.py
similarity index 100%
rename from streamlit_extras/badges/__init__.py
rename to src/streamlit_extras/badges/__init__.py
diff --git a/streamlit_extras/chart_annotations/__init__.py b/src/streamlit_extras/chart_annotations/__init__.py
similarity index 100%
rename from streamlit_extras/chart_annotations/__init__.py
rename to src/streamlit_extras/chart_annotations/__init__.py
diff --git a/streamlit_extras/colored_header/__init__.py b/src/streamlit_extras/colored_header/__init__.py
similarity index 100%
rename from streamlit_extras/colored_header/__init__.py
rename to src/streamlit_extras/colored_header/__init__.py
diff --git a/streamlit_extras/dataframe_explorer/__init__.py b/src/streamlit_extras/dataframe_explorer/__init__.py
similarity index 100%
rename from streamlit_extras/dataframe_explorer/__init__.py
rename to src/streamlit_extras/dataframe_explorer/__init__.py
diff --git a/streamlit_extras/echo_expander/__init__.py b/src/streamlit_extras/echo_expander/__init__.py
similarity index 100%
rename from streamlit_extras/echo_expander/__init__.py
rename to src/streamlit_extras/echo_expander/__init__.py
diff --git a/streamlit_extras/embed_code/__init__.py b/src/streamlit_extras/embed_code/__init__.py
similarity index 100%
rename from streamlit_extras/embed_code/__init__.py
rename to src/streamlit_extras/embed_code/__init__.py
diff --git a/streamlit_extras/function_explorer/__init__.py b/src/streamlit_extras/function_explorer/__init__.py
similarity index 100%
rename from streamlit_extras/function_explorer/__init__.py
rename to src/streamlit_extras/function_explorer/__init__.py
diff --git a/streamlit_extras/image_in_tables/__init__.py b/src/streamlit_extras/image_in_tables/__init__.py
similarity index 100%
rename from streamlit_extras/image_in_tables/__init__.py
rename to src/streamlit_extras/image_in_tables/__init__.py
diff --git a/streamlit_extras/keyboard_text/__init__.py b/src/streamlit_extras/keyboard_text/__init__.py
similarity index 100%
rename from streamlit_extras/keyboard_text/__init__.py
rename to src/streamlit_extras/keyboard_text/__init__.py
diff --git a/streamlit_extras/keyboard_url/__init__.py b/src/streamlit_extras/keyboard_url/__init__.py
similarity index 100%
rename from streamlit_extras/keyboard_url/__init__.py
rename to src/streamlit_extras/keyboard_url/__init__.py
diff --git a/streamlit_extras/let_it_rain/__init__.py b/src/streamlit_extras/let_it_rain/__init__.py
similarity index 100%
rename from streamlit_extras/let_it_rain/__init__.py
rename to src/streamlit_extras/let_it_rain/__init__.py
diff --git a/streamlit_extras/mention/__init__.py b/src/streamlit_extras/mention/__init__.py
similarity index 100%
rename from streamlit_extras/mention/__init__.py
rename to src/streamlit_extras/mention/__init__.py
diff --git a/streamlit_extras/stodo/__init__.py b/src/streamlit_extras/stodo/__init__.py
similarity index 98%
rename from streamlit_extras/stodo/__init__.py
rename to src/streamlit_extras/stodo/__init__.py
index 2b13da4..f53c9d6 100644
--- a/streamlit_extras/stodo/__init__.py
+++ b/src/streamlit_extras/stodo/__init__.py
@@ -1,4 +1,4 @@
-import streamlit_patches as st
+import streamlit as st
 
 
 def to_do(st_commands, checkbox_id):


Test patch:
diff --git a/streamlit_extras/stoggle/__init__.py b/src/streamlit_extras/stoggle/__init__.py
similarity index 100%
rename from streamlit_extras/stoggle/__init__.py
rename to src/streamlit_extras/stoggle/__init__.py
diff --git a/streamlit_extras/switch_page_button/__init__.py b/src/streamlit_extras/switch_page_button/__init__.py
similarity index 100%
rename from streamlit_extras/switch_page_button/__init__.py
rename to src/streamlit_extras/switch_page_button/__init__.py
diff --git a/streamlit_extras/word_importances/__init__.py b/src/streamlit_extras/word_importances/__init__.py
similarity index 100%
rename from streamlit_extras/word_importances/__init__.py
rename to src/streamlit_extras/word_importances/__init__.py
diff --git a/tests/test_extras.py b/tests/test_extras.py
index 81378dd..637db56 100644
--- a/tests/test_extras.py
+++ b/tests/test_extras.py
@@ -1,24 +1,19 @@
+import pkgutil
 from importlib import import_module
-from pathlib import Path
 from typing import List
 
 import pytest
 
-PATH_TO_EXTRAS = "streamlit_extras"
+import streamlit_extras
 
 
 def get_extras() -> List[str]:
-    extra_names = [
-        folder.name
-        for folder in Path(PATH_TO_EXTRAS).glob("*")
-        if folder.is_dir() and folder.name != "__pycache__"
-    ]
-    return extra_names
+    return [extra.name for extra in pkgutil.iter_modules(streamlit_extras.__path__)]
 
 
 @pytest.mark.parametrize("extra", get_extras())
 def test_extra_attributes(extra: str):
-    mod = import_module(f"{PATH_TO_EXTRAS}.{extra}")
+    mod = import_module(f"streamlit_extras.{extra}")
     assert type(mod.__title__) == str
     assert type(mod.__icon__) == str
     assert type(mod.__desc__) == str