Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Project: awesome-streamlit #107

Open
4 of 5 tasks
MarcSkovMadsen opened this issue Oct 18, 2019 · 8 comments
Open
4 of 5 tasks

Add Project: awesome-streamlit #107

MarcSkovMadsen opened this issue Oct 18, 2019 · 8 comments

Comments

@MarcSkovMadsen
Copy link

MarcSkovMadsen commented Oct 18, 2019

Basic info

Application name: Awesome Streamlit
Application repo link: https://github.com/marcskovmadsen/awesome-streamlit
Application home link: https://awesome-streamlit.org/
Application Docs: https://awesome-streamlit.readthedocs.io/
Application Docker Image: https://cloud.docker.com/u/marcskovmadsen/repository/docker/marcskovmadsen/awesome-streamlit
Application Package: https://pypi.org/project/streamlit/
Application description:

The purpose of the Awesome Streamlit Application is to share knowledge on how Awesome Streamlit is and can become as a technology for building (data) applications in Python.

This application provides

  • A list of awesome Streamlit resources.
  • A gallery of awesome streamlit applications.
  • A vision on how awesome Streamlit can be.

Animation

Qualifications

  • Free software with an online source repository.
  • Using Python for a considerable part of their functionality.
  • Well-known, or at least prominently used in an identifiable niche.
  • Maintained or otherwise demonstrably still functional on relevant platforms.
  • An application, not a library or framework.

The application and repo is new. But the reason why I believe this application is important is because it is the first application to take advantage of the Streamlit framework which has the potential to significantly lower the friction required to develop (applications) in Python.

It's so easy and awesome. See this 4 minute introduction to Streamlit

Introduction to Streamlit

I believe the Streamlit Technology will foster a flood of awesome (micro) apps in Python. So the Streamlit technology is important to your list :-)

The application and repo already provides and will provide tons on information on how to develop, test, build and release these types of applications.

If you have helpfull helps or suggestions feel free to add them to the comments

Best regards and thanks.

Marc

@MarcSkovMadsen
Copy link
Author

MarcSkovMadsen commented Oct 18, 2019

I'm just listening to the awesome "Talk Python Podcast" where you are joking about "let's be realistic. You will need html and javascript until they put Python in the browser".

That is no longer true. Streamlit solves this using very efficient caching and communication protocols. And it's very, very performant. They just neeed some more components, style and layout options. But that will come. It's a game changer for web development in Python. I believe :-) And please challenge me :-)

Please checkout the application at

https://awesome-streamlit.org/

@MarcSkovMadsen
Copy link
Author

MarcSkovMadsen commented Oct 18, 2019

@MarcSkovMadsen
Copy link
Author

image

@MarcSkovMadsen
Copy link
Author

MarcSkovMadsen commented Oct 18, 2019

And the source code for the Spreadsheet gallery example is

"""Page to show that its really easy to create a Spreadsheet like application"""
import pandas as pd
import streamlit as st


@st.cache
def get_biostats_data(url) -> pd.DataFrame:
    """A DataFrame of data from https://people.sc.fsu.edu/~jburkardt/data/csv/biostats.csv

    Returns:
        pd.DataFrame -- [description]
    """
    data = pd.read_csv(url)
    columns = {
        "Name": "Name",
        '     "Sex"': "Sex",
        ' "Age"': "Age",
        ' "Height (in)"': "Height (in)",
        ' "Weight (lbs)"': "Weight (lbs)",
    }
    data = data.rename(columns=columns)
    return data


@st.cache
def transform_biostats_data(source_data: pd.DataFrame) -> pd.DataFrame:
    return source_data


@st.cache
def get_grades_data(url: str) -> pd.DataFrame:
    source_data = pd.read_csv(source_url)
    columns = {
        "Last name": "Last name",
        ' "First name"': "First name",
        ' "SSN"': "SSN",
        '        "Test1"': "Test1",
        ' "Test2"': "Test2",
        ' "Test3"': "Test3",
        ' "Test4"': "Test4",
        ' "Final"': "Final",
        ' "Grade"': "Grade",
    }
    source_data = source_data.rename(columns=columns)
    source_data["Test1"] = pd.to_numeric(source_data["Test1"], errors="coerce")
    source_data["First name"] = source_data["First name"].str.replace('"', "")
    return source_data


@st.cache
def transform_grades_data(source_data: pd.DataFrame) -> pd.DataFrame:
    # Add formulas
    transform_data = source_data.copy()
    transform_data["Test Mean"] = (
        transform_data[["Test1", "Test2", "Test3", "Test4"]].mean(axis=1).round()
    )
    transform_data["Relative diff from 1 to 4 (%)"] = (
        (transform_data["Test4"] - transform_data["Test1"])
        / transform_data["Test1"]
        * 100
    ).round()
    return transform_data


st.markdown(
    """
This app illustrates that it's so easy to create high quality spreadsheet like apps
 with [Streamlit](https://streamlit.io). You can **change the sheet** or **hide/show**
 the source data via the sidebar!"""
)

st.sidebar.title("Spreadsheet")
sheet = st.sidebar.selectbox("Select Sheet", ["Biostats", "Grades"])
show_source_data = st.sidebar.checkbox("Show Source Data", value=True)

st.write(f"""## {sheet}""")

if sheet == "Biostats":
    with st.spinner("Loading source data ..."):
        source_url = "https://people.sc.fsu.edu/~jburkardt/data/csv/biostats.csv"
        source_data = get_biostats_data(source_url)
        transform_data = transform_biostats_data(source_data)
        measures = ["Age", "Height (in)", "Weight (lbs)"]

    # Show
    measure = st.selectbox("Measure", ["Age", "Height (in)", "Weight (lbs)"])
    with st.spinner("Updating plot ..."):
        selected = pd.DataFrame(transform_data[measure])
        st.bar_chart(selected)


elif sheet == "Grades":
    with st.spinner("Loading source data ..."):
        source_url = "https://people.sc.fsu.edu/~jburkardt/data/csv/grades.csv"
        source_data = get_grades_data(source_url)
        transform_data = transform_grades_data(source_data)

    # Show
    st.write(  # pylint-disable=line-too-long
        "I illustrate a calculation by calculating the Test Mean."
        " After that we illustrate a calculation to show how much better the students did"
        " the 4th test compared to 1st one.",
        transform_data[
            [
                "First name",
                "Last name",
                "Test1",
                "Test2",
                "Test3",
                "Test4",
                "Test Mean",
                "Relative diff from 1 to 4 (%)",
            ]
        ],
    )
# Show Soure
if show_source_data:
    st.subheader("Source Data")
    st.markdown(f"[{source_url}]({source_url})")
    st.dataframe(source_data)

@MarcSkovMadsen
Copy link
Author

MarcSkovMadsen commented Oct 18, 2019

Ines Montani the author behind Spacy put out this one

image

and the code is

import streamlit as st
import spacy
from spacy import displacy
import pandas as pd


SPACY_MODEL_NAMES = ["en_core_web_sm", "en_core_web_md", "de_core_news_sm"]
DEFAULT_TEXT = "Mark Zuckerberg is the CEO of Facebook."
HTML_WRAPPER = """<div style="overflow-x: auto; border: 1px solid #e6e9ef; border-radius: 0.25rem; padding: 1rem; margin-bottom: 2.5rem">{}</div>"""


@st.cache(ignore_hash=True)
def load_model(name):
    return spacy.load(name)


@st.cache(ignore_hash=True)
def process_text(model_name, text):
    nlp = load_model(model_name)
    return nlp(text)


st.sidebar.title("Interactive spaCy visualizer")
st.sidebar.markdown(
    """
Process text with [spaCy](https://spacy.io) models and visualize named entities,
dependencies and more. Uses spaCy's built-in
[displaCy](http://spacy.io/usage/visualizers) visualizer under the hood.
"""
)

spacy_model = st.sidebar.selectbox("Model name", SPACY_MODEL_NAMES)
model_load_state = st.info(f"Loading model '{spacy_model}'...")
nlp = load_model(spacy_model)
model_load_state.empty()

text = st.text_area("Text to analyze", DEFAULT_TEXT)
doc = process_text(spacy_model, text)

if "parser" in nlp.pipe_names:
    st.header("Dependency Parse & Part-of-speech tags")
    st.sidebar.header("Dependency Parse")
    split_sents = st.sidebar.checkbox("Split sentences", value=True)
    collapse_punct = st.sidebar.checkbox("Collapse punctuation", value=True)
    collapse_phrases = st.sidebar.checkbox("Collapse phrases")
    compact = st.sidebar.checkbox("Compact mode")
    options = {
        "collapse_punct": collapse_punct,
        "collapse_phrases": collapse_phrases,
        "compact": compact,
    }
    docs = [span.as_doc() for span in doc.sents] if split_sents else [doc]
    for sent in docs:
        html = displacy.render(sent, options=options)
        # Double newlines seem to mess with the rendering
        html = html.replace("\n\n", "\n")
        if split_sents and len(docs) > 1:
            st.markdown(f"> {sent.text}")
        st.write(HTML_WRAPPER.format(html), unsafe_allow_html=True)

if "ner" in nlp.pipe_names:
    st.header("Named Entities")
    st.sidebar.header("Named Entities")
    default_labels = ["PERSON", "ORG", "GPE", "LOC"]
    labels = st.sidebar.multiselect(
        "Entity labels", nlp.get_pipe("ner").labels, default_labels
    )
    html = displacy.render(doc, style="ent", options={"ents": labels})
    # Newlines seem to mess with the rendering
    html = html.replace("\n", " ")
    st.write(HTML_WRAPPER.format(html), unsafe_allow_html=True)
    attrs = ["text", "label_", "start", "end", "start_char", "end_char"]
    if "entity_linker" in nlp.pipe_names:
        attrs.append("kb_id_")
    data = [
        [str(getattr(ent, attr)) for attr in attrs]
        for ent in doc.ents
        if ent.label_ in labels
    ]
    df = pd.DataFrame(data, columns=attrs)
    st.dataframe(df)


if "textcat" in nlp.pipe_names:
    st.header("Text Classification")
    st.markdown(f"> {text}")
    df = pd.DataFrame(doc.cats.items(), columns=("Label", "Score"))
    st.dataframe(df)


vector_size = nlp.meta.get("vectors", {}).get("width", 0)
if vector_size:
    st.header("Vectors & Similarity")
    st.code(nlp.meta["vectors"])
    text1 = st.text_input("Text or word 1", "apple")
    text2 = st.text_input("Text or word 2", "orange")
    doc1 = process_text(spacy_model, text1)
    doc2 = process_text(spacy_model, text2)
    similarity = doc1.similarity(doc2)
    if similarity > 0.5:
        st.success(similarity)
    else:
        st.error(similarity)

st.header("Token attributes")

if st.button("Show token attributes"):
    attrs = [
        "idx",
        "text",
        "lemma_",
        "pos_",
        "tag_",
        "dep_",
        "head",
        "ent_type_",
        "ent_iob_",
        "shape_",
        "is_alpha",
        "is_ascii",
        "is_digit",
        "is_punct",
        "like_num",
    ]
    data = [[str(getattr(token, attr)) for attr in attrs] for token in doc]
    df = pd.DataFrame(data, columns=attrs)
    st.dataframe(df)


st.header("JSON Doc")
if st.button("Show JSON Doc"):
    st.json(doc.to_json())

st.header("JSON model meta")
if st.button("Show JSON model meta"):
    st.json(nlp.meta)

@mahmoud
Copy link
Owner

mahmoud commented Oct 18, 2019

Very interesting! Certainly seems like a new class of application is emerging. For the record, it still uses js/typescript, but it's great that the application developer doesn't have to write it themselves. I'll have to take a bit of time to evaluate this new approach, especially as it's still emerging. Thanks for bringing it to my attention!

@treuille
Copy link

As the admittedly biased co-creator of Streamlit. I agree that would be totally awesome to include awesome streamlit in awesome python. What could be more meta? Or more awesome? Or more pythonic? ;-)

Seriously though, please let me know if I can answer any questions or in any way help this effort!

@MarcSkovMadsen
Copy link
Author

MarcSkovMadsen commented Oct 19, 2019

Thanks @mahmoud . Yes it definately uses js/ typescript :-) But let the really skilled front end developers do that. They can develop general web components to be used by Streamlit. And let the rest of us from hobbyist to rockstar pythonista get our things done.

I've updated the first post above with a video animation and an image of the youtube video because I think they are awesome.

I know that you might not think awesome-streamlit.org is awesome (enough yet :-)). But I believe Streamlit is or could be a game changer for awesome python apps in general.

Have a nice weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants