We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
docs: move away from .execute() in favor of explicit methods
### What happened?

per https://github.com/ibis-project/ibis/issues/6351, opening this to track updating docs

### What version of ibis are you using?

n/a

### What backend(s) are you using, if any?

n/a

### Relevant log output

_No response_

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `docs/example_streamlit_app/example_streamlit_app.py`
Content:
```
1 import requests
2 import streamlit as st
3 
4 from ibis import _
5 from ibis.streamlit import IbisConnection
6 
7 st.set_page_config(page_title="Yummy Data", layout="wide")
8 st.title("Yummy Data :bacon:")
9 
10 
11 @st.cache_data
12 def get_emoji():
13     resp = requests.get(
14         "https://raw.githubusercontent.com/omnidan/node-emoji/master/lib/emoji.json"
15     )
16     resp.raise_for_status()
17     emojis = resp.json()
18     return emojis
19 
20 
21 options = [1, 5, 10, 25, 50, 100]
22 
23 
24 @st.cache_data
25 def query():
26     return (
27         con.tables.recipes.relabel("snake_case")
28         .mutate(ner=_.ner.map(lambda n: n.lower()).unnest())
29         .ner.topk(max(options))
30         .relabel(dict(ner="ingredient"))
31         .execute()
32         .assign(
33             emoji=lambda df: df.ingredient.map(
34                 lambda emoji: f"{emojis.get(emoji, '-')}"
35             )
36         )
37         .set_index("ingredient")
38     )
39 
40 
41 emojis = get_emoji()
42 
43 con = st.experimental_connection("ch", type=IbisConnection)
44 
45 if n := st.radio("Ingredients", options, index=1, horizontal=True):
46     table, whole = st.columns((2, 1))
47     idx = options.index(n)
48     k = 0
49     base = query()
50     for m in options[: idx + 1]:
51         df = base.iloc[k:m]
52         if not k:
53             word = "first"
54         elif m < n:
55             word = "next"
56         else:
57             word = "last"
58 
59         uniq_emojis = " ".join(df.emoji[df.emoji != "-"].unique())
60         table.header(f"{word.title()} {m - k:d}")
61         table.subheader(uniq_emojis)
62 
63         table.dataframe(df, use_container_width=True)
64         k = m
65 
66     b = base.iloc[:n]
67     uniq_emojis = " ".join(b.emoji[b.emoji != "-"].unique())
68     whole.header(f"Top {n:d}")
69     whole.subheader(uniq_emojis)
70     whole.dataframe(b, use_container_width=True)
71
```

Path: `docs/backends/app/backend_info_app.py`
Content:
```
1 import datetime
2 import tempfile
3 from pathlib import Path
4 from typing import List, Optional
5 
6 import pandas as pd
7 import requests
8 import sqlglot
9 import streamlit as st
10 
11 import ibis
12 from ibis import _
13 
14 ONE_HOUR_IN_SECONDS = datetime.timedelta(hours=1).total_seconds()
15 
16 st.set_page_config(layout='wide')
17 
18 # Track all queries. We display them at the bottom of the page.
19 ibis.options.verbose = True
20 sql_queries = []
21 ibis.options.verbose_log = lambda sql: sql_queries.append(sql)
22 
23 
24 @st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)
25 def support_matrix_df():
26     resp = requests.get("https://ibis-project.org/backends/raw_support_matrix.csv")
27     resp.raise_for_status()
28 
29     with tempfile.NamedTemporaryFile() as f:
30         f.write(resp.content)
31         return (
32             ibis.read_csv(f.name)
33             .relabel({'FullOperation': 'full_operation'})
34             .mutate(
35                 short_operation=_.full_operation.split(".")[-1],
36                 operation_category=_.full_operation.split(".")[-2],
37             )
38             .execute()
39         )
40 
41 
42 @st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)
43 def backends_info_df():
44     return pd.DataFrame(
45         {
46             "bigquery": ["string", "sql"],
47             "clickhouse": ["string", "sql"],
48             "dask": ["dataframe"],
49             "datafusion": ["sql"],
50             "druid": ["sqlalchemy", "sql"],
51             "duckdb": ["sqlalchemy", "sql"],
52             "impala": ["string", "sql"],
53             "mssql": ["sqlalchemy", "sql"],
54             "mysql": ["sqlalchemy", "sql"],
55             "oracle": ["sqlalchemy", "sql"],
56             "pandas": ["dataframe"],
57             "polars": ["dataframe"],
58             "postgres": ["sqlalchemy", "sql"],
59             "pyspark": ["dataframe"],
60             "snowflake": ["sqlalchemy", "sql"],
61             "sqlite": ["sqlalchemy", "sql"],
62             "trino": ["sqlalchemy", "sql"],
63         }.items(),
64         columns=['backend_name', 'categories'],
65     )
66 
67 
68 backend_info_table = ibis.memtable(backends_info_df())
69 support_matrix_table = ibis.memtable(support_matrix_df())
70 
71 
72 @st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)
73 def get_all_backend_categories():
74     return (
75         backend_info_table.select(category=_.categories.unnest())
76         .distinct()
77         .order_by('category')['category']
78         .execute()
79         .tolist()
80     )
81 
82 
83 @st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)
84 def get_all_operation_categories():
85     return (
86         support_matrix_table.select(_.operation_category)
87         .distinct()['operation_category']
88         .execute()
89         .tolist()
90     )
91 
92 
93 @st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)
94 def get_backend_names(categories: Optional[List[str]] = None):
95     backend_expr = backend_info_table.mutate(category=_.categories.unnest())
96     if categories:
97         backend_expr = backend_expr.filter(_.category.isin(categories))
98     return (
99         backend_expr.select(_.backend_name).distinct().backend_name.execute().tolist()
100     )
101 
102 
103 def get_selected_backend_name():
104     backend_categories = get_all_backend_categories()
105     selected_categories_names = st.sidebar.multiselect(
106         'Backend category',
107         options=backend_categories,
108         default=None,
109     )
110     if not selected_categories_names:
111         return get_backend_names()
112     return get_backend_names(selected_categories_names)
113 
114 
115 def get_selected_operation_categories():
116     all_ops_categories = get_all_operation_categories()
117 
118     selected_ops_categories = st.sidebar.multiselect(
119         'Operation category',
120         options=sorted(all_ops_categories),
121         default=None,
122     )
123     if not selected_ops_categories:
124         selected_ops_categories = all_ops_categories
125     show_geospatial = st.sidebar.checkbox('Include Geospatial ops', value=True)
126     if not show_geospatial and 'geospatial' in selected_ops_categories:
127         selected_ops_categories.remove("geospatial")
128     return selected_ops_categories
129 
130 
131 current_backend_names = get_selected_backend_name()
132 sort_by_coverage = st.sidebar.checkbox('Sort by API Coverage', value=False)
133 current_ops_categories = get_selected_operation_categories()
134 
135 hide_supported_by_all_backends = st.sidebar.selectbox(
136     'Operation compatibility',
137     ['Show all', 'Show supported by all backends', 'Hide supported by all backends'],
138     0,
139 )
140 show_full_ops_name = st.sidebar.checkbox('Show full operation name', False)
141 
142 # Start ibis expression
143 table_expr = support_matrix_table
144 
145 # Add index to result
146 if show_full_ops_name:
147     table_expr = table_expr.mutate(index=_.full_operation)
148 else:
149     table_expr = table_expr.mutate(index=_.short_operation)
150 table_expr = table_expr.order_by(_.index)
151 
152 # Filter operations by selected categories
153 table_expr = table_expr.filter(_.operation_category.isin(current_ops_categories))
154 
155 # Filter operation by compatibility
156 supported_backend_count = sum(
157     getattr(table_expr, backend_name).ifelse(1, 0)
158     for backend_name in current_backend_names
159 )
160 if hide_supported_by_all_backends == 'Show supported by all backends':
161     table_expr = table_expr.filter(
162         supported_backend_count == len(current_backend_names)
163     )
164 elif hide_supported_by_all_backends == 'Hide supported by all backends':
165     table_expr = table_expr.filter(
166         supported_backend_count != len(current_backend_names)
167     )
168 
169 # Show only selected backend
170 table_expr = table_expr[current_backend_names + ["index"]]
171 
172 # Execute query
173 df = table_expr.execute()
174 df = df.set_index('index')
175 
176 # Display result
177 all_visible_ops_count = len(df.index)
178 if all_visible_ops_count:
179     # Compute coverage
180     coverage = (
181         df.sum()
182         .sort_values(ascending=False)
183         .map(lambda n: f"{n} ({round(100 * n / all_visible_ops_count)}%)")
184         .to_frame(name="API Coverage")
185         .T
186     )
187 
188     table = pd.concat([coverage, df.replace({True: "✔", False: "🚫"})]).loc[
189         :, slice(None) if sort_by_coverage else sorted(df.columns)
190     ]
191     st.dataframe(table)
192 else:
193     st.write("No data")
194 
195 with st.expander("SQL queries"):
196     for sql_query in sql_queries:
197         pretty_sql_query = sqlglot.transpile(
198             sql_query, read='duckdb', write='duckdb', pretty=True
199         )[0]
200         st.code(pretty_sql_query, language='sql')
201 
202 with st.expander("Source code"):
203     st.code(Path(__file__).read_text())
204
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/docs/backends/app/backend_info_app.py b/docs/backends/app/backend_info_app.py
--- a/docs/backends/app/backend_info_app.py
+++ b/docs/backends/app/backend_info_app.py
@@ -35,7 +35,7 @@
                 short_operation=_.full_operation.split(".")[-1],
                 operation_category=_.full_operation.split(".")[-2],
             )
-            .execute()
+            .to_pandas()
         )
 
 
@@ -75,7 +75,7 @@
         backend_info_table.select(category=_.categories.unnest())
         .distinct()
         .order_by('category')['category']
-        .execute()
+        .to_pandas()
         .tolist()
     )
 
@@ -85,7 +85,7 @@
     return (
         support_matrix_table.select(_.operation_category)
         .distinct()['operation_category']
-        .execute()
+        .to_pandas()
         .tolist()
     )
 
@@ -96,7 +96,7 @@
     if categories:
         backend_expr = backend_expr.filter(_.category.isin(categories))
     return (
-        backend_expr.select(_.backend_name).distinct().backend_name.execute().tolist()
+        backend_expr.select(_.backend_name).distinct().backend_name.to_pandas().tolist()
     )
 
 
@@ -170,7 +170,7 @@
 table_expr = table_expr[current_backend_names + ["index"]]
 
 # Execute query
-df = table_expr.execute()
+df = table_expr.to_pandas()
 df = df.set_index('index')
 
 # Display result
diff --git a/docs/example_streamlit_app/example_streamlit_app.py b/docs/example_streamlit_app/example_streamlit_app.py
--- a/docs/example_streamlit_app/example_streamlit_app.py
+++ b/docs/example_streamlit_app/example_streamlit_app.py
@@ -28,7 +28,7 @@
         .mutate(ner=_.ner.map(lambda n: n.lower()).unnest())
         .ner.topk(max(options))
         .relabel(dict(ner="ingredient"))
-        .execute()
+        .to_pandas()
         .assign(
             emoji=lambda df: df.ingredient.map(
                 lambda emoji: f"{emojis.get(emoji, '-')}"

{"golden_diff": "diff --git a/docs/backends/app/backend_info_app.py b/docs/backends/app/backend_info_app.py\n--- a/docs/backends/app/backend_info_app.py\n+++ b/docs/backends/app/backend_info_app.py\n@@ -35,7 +35,7 @@\n                 short_operation=_.full_operation.split(\".\")[-1],\n                 operation_category=_.full_operation.split(\".\")[-2],\n             )\n-            .execute()\n+            .to_pandas()\n         )\n \n \n@@ -75,7 +75,7 @@\n         backend_info_table.select(category=_.categories.unnest())\n         .distinct()\n         .order_by('category')['category']\n-        .execute()\n+        .to_pandas()\n         .tolist()\n     )\n \n@@ -85,7 +85,7 @@\n     return (\n         support_matrix_table.select(_.operation_category)\n         .distinct()['operation_category']\n-        .execute()\n+        .to_pandas()\n         .tolist()\n     )\n \n@@ -96,7 +96,7 @@\n     if categories:\n         backend_expr = backend_expr.filter(_.category.isin(categories))\n     return (\n-        backend_expr.select(_.backend_name).distinct().backend_name.execute().tolist()\n+        backend_expr.select(_.backend_name).distinct().backend_name.to_pandas().tolist()\n     )\n \n \n@@ -170,7 +170,7 @@\n table_expr = table_expr[current_backend_names + [\"index\"]]\n \n # Execute query\n-df = table_expr.execute()\n+df = table_expr.to_pandas()\n df = df.set_index('index')\n \n # Display result\ndiff --git a/docs/example_streamlit_app/example_streamlit_app.py b/docs/example_streamlit_app/example_streamlit_app.py\n--- a/docs/example_streamlit_app/example_streamlit_app.py\n+++ b/docs/example_streamlit_app/example_streamlit_app.py\n@@ -28,7 +28,7 @@\n         .mutate(ner=_.ner.map(lambda n: n.lower()).unnest())\n         .ner.topk(max(options))\n         .relabel(dict(ner=\"ingredient\"))\n-        .execute()\n+        .to_pandas()\n         .assign(\n             emoji=lambda df: df.ingredient.map(\n                 lambda emoji: f\"{emojis.get(emoji, '-')}\"\n", "issue": "docs: move away from .execute() in favor of explicit methods\n### What happened?\n\nper https://github.com/ibis-project/ibis/issues/6351, opening this to track updating docs\n\n### What version of ibis are you using?\n\nn/a\n\n### What backend(s) are you using, if any?\n\nn/a\n\n### Relevant log output\n\n_No response_\n\n### Code of Conduct\n\n- [X] I agree to follow this project's Code of Conduct\n", "before_files": [{"content": "import requests\nimport streamlit as st\n\nfrom ibis import _\nfrom ibis.streamlit import IbisConnection\n\nst.set_page_config(page_title=\"Yummy Data\", layout=\"wide\")\nst.title(\"Yummy Data :bacon:\")\n\n\n@st.cache_data\ndef get_emoji():\n    resp = requests.get(\n        \"https://raw.githubusercontent.com/omnidan/node-emoji/master/lib/emoji.json\"\n    )\n    resp.raise_for_status()\n    emojis = resp.json()\n    return emojis\n\n\noptions = [1, 5, 10, 25, 50, 100]\n\n\n@st.cache_data\ndef query():\n    return (\n        con.tables.recipes.relabel(\"snake_case\")\n        .mutate(ner=_.ner.map(lambda n: n.lower()).unnest())\n        .ner.topk(max(options))\n        .relabel(dict(ner=\"ingredient\"))\n        .execute()\n        .assign(\n            emoji=lambda df: df.ingredient.map(\n                lambda emoji: f\"{emojis.get(emoji, '-')}\"\n            )\n        )\n        .set_index(\"ingredient\")\n    )\n\n\nemojis = get_emoji()\n\ncon = st.experimental_connection(\"ch\", type=IbisConnection)\n\nif n := st.radio(\"Ingredients\", options, index=1, horizontal=True):\n    table, whole = st.columns((2, 1))\n    idx = options.index(n)\n    k = 0\n    base = query()\n    for m in options[: idx + 1]:\n        df = base.iloc[k:m]\n        if not k:\n            word = \"first\"\n        elif m < n:\n            word = \"next\"\n        else:\n            word = \"last\"\n\n        uniq_emojis = \" \".join(df.emoji[df.emoji != \"-\"].unique())\n        table.header(f\"{word.title()} {m - k:d}\")\n        table.subheader(uniq_emojis)\n\n        table.dataframe(df, use_container_width=True)\n        k = m\n\n    b = base.iloc[:n]\n    uniq_emojis = \" \".join(b.emoji[b.emoji != \"-\"].unique())\n    whole.header(f\"Top {n:d}\")\n    whole.subheader(uniq_emojis)\n    whole.dataframe(b, use_container_width=True)\n", "path": "docs/example_streamlit_app/example_streamlit_app.py"}, {"content": "import datetime\nimport tempfile\nfrom pathlib import Path\nfrom typing import List, Optional\n\nimport pandas as pd\nimport requests\nimport sqlglot\nimport streamlit as st\n\nimport ibis\nfrom ibis import _\n\nONE_HOUR_IN_SECONDS = datetime.timedelta(hours=1).total_seconds()\n\nst.set_page_config(layout='wide')\n\n# Track all queries. We display them at the bottom of the page.\nibis.options.verbose = True\nsql_queries = []\nibis.options.verbose_log = lambda sql: sql_queries.append(sql)\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef support_matrix_df():\n    resp = requests.get(\"https://ibis-project.org/backends/raw_support_matrix.csv\")\n    resp.raise_for_status()\n\n    with tempfile.NamedTemporaryFile() as f:\n        f.write(resp.content)\n        return (\n            ibis.read_csv(f.name)\n            .relabel({'FullOperation': 'full_operation'})\n            .mutate(\n                short_operation=_.full_operation.split(\".\")[-1],\n                operation_category=_.full_operation.split(\".\")[-2],\n            )\n            .execute()\n        )\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef backends_info_df():\n    return pd.DataFrame(\n        {\n            \"bigquery\": [\"string\", \"sql\"],\n            \"clickhouse\": [\"string\", \"sql\"],\n            \"dask\": [\"dataframe\"],\n            \"datafusion\": [\"sql\"],\n            \"druid\": [\"sqlalchemy\", \"sql\"],\n            \"duckdb\": [\"sqlalchemy\", \"sql\"],\n            \"impala\": [\"string\", \"sql\"],\n            \"mssql\": [\"sqlalchemy\", \"sql\"],\n            \"mysql\": [\"sqlalchemy\", \"sql\"],\n            \"oracle\": [\"sqlalchemy\", \"sql\"],\n            \"pandas\": [\"dataframe\"],\n            \"polars\": [\"dataframe\"],\n            \"postgres\": [\"sqlalchemy\", \"sql\"],\n            \"pyspark\": [\"dataframe\"],\n            \"snowflake\": [\"sqlalchemy\", \"sql\"],\n            \"sqlite\": [\"sqlalchemy\", \"sql\"],\n            \"trino\": [\"sqlalchemy\", \"sql\"],\n        }.items(),\n        columns=['backend_name', 'categories'],\n    )\n\n\nbackend_info_table = ibis.memtable(backends_info_df())\nsupport_matrix_table = ibis.memtable(support_matrix_df())\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef get_all_backend_categories():\n    return (\n        backend_info_table.select(category=_.categories.unnest())\n        .distinct()\n        .order_by('category')['category']\n        .execute()\n        .tolist()\n    )\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef get_all_operation_categories():\n    return (\n        support_matrix_table.select(_.operation_category)\n        .distinct()['operation_category']\n        .execute()\n        .tolist()\n    )\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef get_backend_names(categories: Optional[List[str]] = None):\n    backend_expr = backend_info_table.mutate(category=_.categories.unnest())\n    if categories:\n        backend_expr = backend_expr.filter(_.category.isin(categories))\n    return (\n        backend_expr.select(_.backend_name).distinct().backend_name.execute().tolist()\n    )\n\n\ndef get_selected_backend_name():\n    backend_categories = get_all_backend_categories()\n    selected_categories_names = st.sidebar.multiselect(\n        'Backend category',\n        options=backend_categories,\n        default=None,\n    )\n    if not selected_categories_names:\n        return get_backend_names()\n    return get_backend_names(selected_categories_names)\n\n\ndef get_selected_operation_categories():\n    all_ops_categories = get_all_operation_categories()\n\n    selected_ops_categories = st.sidebar.multiselect(\n        'Operation category',\n        options=sorted(all_ops_categories),\n        default=None,\n    )\n    if not selected_ops_categories:\n        selected_ops_categories = all_ops_categories\n    show_geospatial = st.sidebar.checkbox('Include Geospatial ops', value=True)\n    if not show_geospatial and 'geospatial' in selected_ops_categories:\n        selected_ops_categories.remove(\"geospatial\")\n    return selected_ops_categories\n\n\ncurrent_backend_names = get_selected_backend_name()\nsort_by_coverage = st.sidebar.checkbox('Sort by API Coverage', value=False)\ncurrent_ops_categories = get_selected_operation_categories()\n\nhide_supported_by_all_backends = st.sidebar.selectbox(\n    'Operation compatibility',\n    ['Show all', 'Show supported by all backends', 'Hide supported by all backends'],\n    0,\n)\nshow_full_ops_name = st.sidebar.checkbox('Show full operation name', False)\n\n# Start ibis expression\ntable_expr = support_matrix_table\n\n# Add index to result\nif show_full_ops_name:\n    table_expr = table_expr.mutate(index=_.full_operation)\nelse:\n    table_expr = table_expr.mutate(index=_.short_operation)\ntable_expr = table_expr.order_by(_.index)\n\n# Filter operations by selected categories\ntable_expr = table_expr.filter(_.operation_category.isin(current_ops_categories))\n\n# Filter operation by compatibility\nsupported_backend_count = sum(\n    getattr(table_expr, backend_name).ifelse(1, 0)\n    for backend_name in current_backend_names\n)\nif hide_supported_by_all_backends == 'Show supported by all backends':\n    table_expr = table_expr.filter(\n        supported_backend_count == len(current_backend_names)\n    )\nelif hide_supported_by_all_backends == 'Hide supported by all backends':\n    table_expr = table_expr.filter(\n        supported_backend_count != len(current_backend_names)\n    )\n\n# Show only selected backend\ntable_expr = table_expr[current_backend_names + [\"index\"]]\n\n# Execute query\ndf = table_expr.execute()\ndf = df.set_index('index')\n\n# Display result\nall_visible_ops_count = len(df.index)\nif all_visible_ops_count:\n    # Compute coverage\n    coverage = (\n        df.sum()\n        .sort_values(ascending=False)\n        .map(lambda n: f\"{n} ({round(100 * n / all_visible_ops_count)}%)\")\n        .to_frame(name=\"API Coverage\")\n        .T\n    )\n\n    table = pd.concat([coverage, df.replace({True: \"\u2714\", False: \"\ud83d\udeab\"})]).loc[\n        :, slice(None) if sort_by_coverage else sorted(df.columns)\n    ]\n    st.dataframe(table)\nelse:\n    st.write(\"No data\")\n\nwith st.expander(\"SQL queries\"):\n    for sql_query in sql_queries:\n        pretty_sql_query = sqlglot.transpile(\n            sql_query, read='duckdb', write='duckdb', pretty=True\n        )[0]\n        st.code(pretty_sql_query, language='sql')\n\nwith st.expander(\"Source code\"):\n    st.code(Path(__file__).read_text())\n", "path": "docs/backends/app/backend_info_app.py"}], "after_files": [{"content": "import requests\nimport streamlit as st\n\nfrom ibis import _\nfrom ibis.streamlit import IbisConnection\n\nst.set_page_config(page_title=\"Yummy Data\", layout=\"wide\")\nst.title(\"Yummy Data :bacon:\")\n\n\n@st.cache_data\ndef get_emoji():\n    resp = requests.get(\n        \"https://raw.githubusercontent.com/omnidan/node-emoji/master/lib/emoji.json\"\n    )\n    resp.raise_for_status()\n    emojis = resp.json()\n    return emojis\n\n\noptions = [1, 5, 10, 25, 50, 100]\n\n\n@st.cache_data\ndef query():\n    return (\n        con.tables.recipes.relabel(\"snake_case\")\n        .mutate(ner=_.ner.map(lambda n: n.lower()).unnest())\n        .ner.topk(max(options))\n        .relabel(dict(ner=\"ingredient\"))\n        .to_pandas()\n        .assign(\n            emoji=lambda df: df.ingredient.map(\n                lambda emoji: f\"{emojis.get(emoji, '-')}\"\n            )\n        )\n        .set_index(\"ingredient\")\n    )\n\n\nemojis = get_emoji()\n\ncon = st.experimental_connection(\"ch\", type=IbisConnection)\n\nif n := st.radio(\"Ingredients\", options, index=1, horizontal=True):\n    table, whole = st.columns((2, 1))\n    idx = options.index(n)\n    k = 0\n    base = query()\n    for m in options[: idx + 1]:\n        df = base.iloc[k:m]\n        if not k:\n            word = \"first\"\n        elif m < n:\n            word = \"next\"\n        else:\n            word = \"last\"\n\n        uniq_emojis = \" \".join(df.emoji[df.emoji != \"-\"].unique())\n        table.header(f\"{word.title()} {m - k:d}\")\n        table.subheader(uniq_emojis)\n\n        table.dataframe(df, use_container_width=True)\n        k = m\n\n    b = base.iloc[:n]\n    uniq_emojis = \" \".join(b.emoji[b.emoji != \"-\"].unique())\n    whole.header(f\"Top {n:d}\")\n    whole.subheader(uniq_emojis)\n    whole.dataframe(b, use_container_width=True)\n", "path": "docs/example_streamlit_app/example_streamlit_app.py"}, {"content": "import datetime\nimport tempfile\nfrom pathlib import Path\nfrom typing import List, Optional\n\nimport pandas as pd\nimport requests\nimport sqlglot\nimport streamlit as st\n\nimport ibis\nfrom ibis import _\n\nONE_HOUR_IN_SECONDS = datetime.timedelta(hours=1).total_seconds()\n\nst.set_page_config(layout='wide')\n\n# Track all queries. We display them at the bottom of the page.\nibis.options.verbose = True\nsql_queries = []\nibis.options.verbose_log = lambda sql: sql_queries.append(sql)\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef support_matrix_df():\n    resp = requests.get(\"https://ibis-project.org/backends/raw_support_matrix.csv\")\n    resp.raise_for_status()\n\n    with tempfile.NamedTemporaryFile() as f:\n        f.write(resp.content)\n        return (\n            ibis.read_csv(f.name)\n            .relabel({'FullOperation': 'full_operation'})\n            .mutate(\n                short_operation=_.full_operation.split(\".\")[-1],\n                operation_category=_.full_operation.split(\".\")[-2],\n            )\n            .to_pandas()\n        )\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef backends_info_df():\n    return pd.DataFrame(\n        {\n            \"bigquery\": [\"string\", \"sql\"],\n            \"clickhouse\": [\"string\", \"sql\"],\n            \"dask\": [\"dataframe\"],\n            \"datafusion\": [\"sql\"],\n            \"druid\": [\"sqlalchemy\", \"sql\"],\n            \"duckdb\": [\"sqlalchemy\", \"sql\"],\n            \"impala\": [\"string\", \"sql\"],\n            \"mssql\": [\"sqlalchemy\", \"sql\"],\n            \"mysql\": [\"sqlalchemy\", \"sql\"],\n            \"oracle\": [\"sqlalchemy\", \"sql\"],\n            \"pandas\": [\"dataframe\"],\n            \"polars\": [\"dataframe\"],\n            \"postgres\": [\"sqlalchemy\", \"sql\"],\n            \"pyspark\": [\"dataframe\"],\n            \"snowflake\": [\"sqlalchemy\", \"sql\"],\n            \"sqlite\": [\"sqlalchemy\", \"sql\"],\n            \"trino\": [\"sqlalchemy\", \"sql\"],\n        }.items(),\n        columns=['backend_name', 'categories'],\n    )\n\n\nbackend_info_table = ibis.memtable(backends_info_df())\nsupport_matrix_table = ibis.memtable(support_matrix_df())\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef get_all_backend_categories():\n    return (\n        backend_info_table.select(category=_.categories.unnest())\n        .distinct()\n        .order_by('category')['category']\n        .to_pandas()\n        .tolist()\n    )\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef get_all_operation_categories():\n    return (\n        support_matrix_table.select(_.operation_category)\n        .distinct()['operation_category']\n        .to_pandas()\n        .tolist()\n    )\n\n\n@st.experimental_memo(ttl=ONE_HOUR_IN_SECONDS)\ndef get_backend_names(categories: Optional[List[str]] = None):\n    backend_expr = backend_info_table.mutate(category=_.categories.unnest())\n    if categories:\n        backend_expr = backend_expr.filter(_.category.isin(categories))\n    return (\n        backend_expr.select(_.backend_name).distinct().backend_name.to_pandas().tolist()\n    )\n\n\ndef get_selected_backend_name():\n    backend_categories = get_all_backend_categories()\n    selected_categories_names = st.sidebar.multiselect(\n        'Backend category',\n        options=backend_categories,\n        default=None,\n    )\n    if not selected_categories_names:\n        return get_backend_names()\n    return get_backend_names(selected_categories_names)\n\n\ndef get_selected_operation_categories():\n    all_ops_categories = get_all_operation_categories()\n\n    selected_ops_categories = st.sidebar.multiselect(\n        'Operation category',\n        options=sorted(all_ops_categories),\n        default=None,\n    )\n    if not selected_ops_categories:\n        selected_ops_categories = all_ops_categories\n    show_geospatial = st.sidebar.checkbox('Include Geospatial ops', value=True)\n    if not show_geospatial and 'geospatial' in selected_ops_categories:\n        selected_ops_categories.remove(\"geospatial\")\n    return selected_ops_categories\n\n\ncurrent_backend_names = get_selected_backend_name()\nsort_by_coverage = st.sidebar.checkbox('Sort by API Coverage', value=False)\ncurrent_ops_categories = get_selected_operation_categories()\n\nhide_supported_by_all_backends = st.sidebar.selectbox(\n    'Operation compatibility',\n    ['Show all', 'Show supported by all backends', 'Hide supported by all backends'],\n    0,\n)\nshow_full_ops_name = st.sidebar.checkbox('Show full operation name', False)\n\n# Start ibis expression\ntable_expr = support_matrix_table\n\n# Add index to result\nif show_full_ops_name:\n    table_expr = table_expr.mutate(index=_.full_operation)\nelse:\n    table_expr = table_expr.mutate(index=_.short_operation)\ntable_expr = table_expr.order_by(_.index)\n\n# Filter operations by selected categories\ntable_expr = table_expr.filter(_.operation_category.isin(current_ops_categories))\n\n# Filter operation by compatibility\nsupported_backend_count = sum(\n    getattr(table_expr, backend_name).ifelse(1, 0)\n    for backend_name in current_backend_names\n)\nif hide_supported_by_all_backends == 'Show supported by all backends':\n    table_expr = table_expr.filter(\n        supported_backend_count == len(current_backend_names)\n    )\nelif hide_supported_by_all_backends == 'Hide supported by all backends':\n    table_expr = table_expr.filter(\n        supported_backend_count != len(current_backend_names)\n    )\n\n# Show only selected backend\ntable_expr = table_expr[current_backend_names + [\"index\"]]\n\n# Execute query\ndf = table_expr.to_pandas()\ndf = df.set_index('index')\n\n# Display result\nall_visible_ops_count = len(df.index)\nif all_visible_ops_count:\n    # Compute coverage\n    coverage = (\n        df.sum()\n        .sort_values(ascending=False)\n        .map(lambda n: f\"{n} ({round(100 * n / all_visible_ops_count)}%)\")\n        .to_frame(name=\"API Coverage\")\n        .T\n    )\n\n    table = pd.concat([coverage, df.replace({True: \"\u2714\", False: \"\ud83d\udeab\"})]).loc[\n        :, slice(None) if sort_by_coverage else sorted(df.columns)\n    ]\n    st.dataframe(table)\nelse:\n    st.write(\"No data\")\n\nwith st.expander(\"SQL queries\"):\n    for sql_query in sql_queries:\n        pretty_sql_query = sqlglot.transpile(\n            sql_query, read='duckdb', write='duckdb', pretty=True\n        )[0]\n        st.code(pretty_sql_query, language='sql')\n\nwith st.expander(\"Source code\"):\n    st.code(Path(__file__).read_text())\n", "path": "docs/backends/app/backend_info_app.py"}]}